View Javadoc
1   /*
2    * Copyright 2009, openv4j.sf.net, and individual contributors as indicated
3    * by the @authors tag. See the copyright.txt in the distribution for a
4    * full listing of individual contributors.
5    *
6    * This is free software; you can redistribute it and/or modify it
7    * under the terms of the GNU General Public License as
8    * published by the Free Software Foundation; either version 3 of
9    * the License, or (at your option) any later version.
10   *
11   * This software is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this software; if not, write to the Free
18   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
20   *
21   * $Id: $
22   *
23   * @author arnep
24   */
25  package net.sf.openv4j.protocolhandlers;
26  
27  /**
28   * DOCUMENT ME!
29   *
30   * @author aploese
31   */
32  public class SegmentedDataContainer extends DataContainer {
33      /**
34       * At least the V200KW2 is capable to fetch all data with 32 byte segmentation
35       */
36      /**
37       * At least the V200KW2 is capable to fetch all data with 32 byte segmentation
38       */
39      public static final int DEFAULT_SEGMENT_SIZE = 32;
40      private DataBlock[] dataSegments;
41      private int segmentSize;
42  
43      /**
44       * Creates a new SegmentedDataContainer object.
45       */
46      public SegmentedDataContainer() {
47          super();
48          setSegmentSize(DEFAULT_SEGMENT_SIZE);
49      }
50  
51      /**
52       * Creates a new SegmentedDataContainer object.
53       *
54       * @param segmentSize DOCUMENT ME!
55       */
56      public SegmentedDataContainer(int segmentSize) {
57          super();
58          setSegmentSize(segmentSize);
59      }
60  
61      /**
62       * DOCUMENT ME!
63       *
64       * @param startAddress DOCUMENT ME!
65       * @param data DOCUMENT ME!
66       *
67       * @throws UnsupportedOperationException DOCUMENT ME!
68       */
69      @Override
70      public void addToDataContainer(int startAddress, int[] data) {
71          throw new UnsupportedOperationException("Write of segmented data is not supported.");
72      }
73  
74      /**
75       * DOCUMENT ME!
76       *
77       * @param startAddress DOCUMENT ME!
78       * @param length DOCUMENT ME!
79       */
80      @Override
81      public void addToDataContainer(int startAddress, int length) {
82          int baseInxed = startAddress / segmentSize;
83  
84          if (dataSegments[baseInxed] == null) {
85              dataSegments[baseInxed] = new DataBlock(baseInxed * segmentSize, segmentSize);
86          }
87  
88          for (int i = 1; i < (length / segmentSize); i++) {
89              baseInxed++;
90  
91              if (dataSegments[baseInxed] == null) {
92                  dataSegments[baseInxed] = new DataBlock(baseInxed * segmentSize, segmentSize);
93              }
94          }
95      }
96  
97      /**
98       * DOCUMENT ME!
99       *
100      * @param index DOCUMENT ME!
101      *
102      * @return DOCUMENT ME!
103      *
104      * @throws IndexOutOfBoundsException DOCUMENT ME!
105      */
106     @Override
107     public DataBlock getDataBlock(int index) {
108         int pos = 0;
109 
110         for (int i = 0; i < dataSegments.length; i++) {
111             if (dataSegments[i] != null) {
112                 if (pos == index) {
113                     return dataSegments[i];
114                 }
115 
116                 pos++;
117             }
118         }
119 
120         throw new IndexOutOfBoundsException("Cant find index " + index);
121     }
122 
123     /**
124      * DOCUMENT ME!
125      *
126      * @return DOCUMENT ME!
127      */
128     @Override
129     public int getDataBlockCount() {
130         int result = 0;
131 
132         for (int i = 0; i < dataSegments.length; i++) {
133             if (dataSegments[i] != null) {
134                 result++;
135             }
136         }
137 
138         return result;
139     }
140 
141     /**
142      * DOCUMENT ME!
143      *
144      * @param currentSendSegmentAddr DOCUMENT ME!
145      *
146      * @return DOCUMENT ME!
147      */
148     public int getNextSegmentAddr(int currentSendSegmentAddr) {
149         if (currentSendSegmentAddr == -1) {
150             for (int i = 0; i < dataSegments.length; i++) {
151                 if (dataSegments[i] != null) {
152                     return i * segmentSize;
153                 }
154             }
155         } else {
156             for (int i = (currentSendSegmentAddr / segmentSize) + 1; i < dataSegments.length; i++) {
157                 if (dataSegments[i] != null) {
158                     return i * segmentSize;
159                 }
160             }
161         }
162 
163         return -1;
164     }
165 
166     /**
167      * DOCUMENT ME!
168      *
169      * @param address DOCUMENT ME!
170      *
171      * @return DOCUMENT ME!
172      */
173     @Override
174     public int getRawByte(int address) {
175         final int baseIndex = address / segmentSize;
176 
177         if (dataSegments[baseIndex] == null) {
178             return 0x00ff;
179         } else {
180             return dataSegments[baseIndex].getByteAtPos(address % segmentSize) & 0x00ff;
181         }
182     }
183 
184     /**
185      * DOCUMENT ME!
186      *
187      * @param addr DOCUMENT ME!
188      * @param theData DOCUMENT ME!
189      */
190     @Override
191     public void setBytes(int addr, byte[] theData) {
192         if (((addr % segmentSize) == 0) && (theData.length == segmentSize)) {
193             dataSegments[addr / segmentSize].setBytesAtPos(addr % segmentSize, theData);
194         } else {
195             super.setBytes(addr, theData);
196         }
197     }
198 
199     /**
200      * DOCUMENT ME!
201      *
202      * @param addr DOCUMENT ME!
203      * @param theData DOCUMENT ME!
204      */
205     @Override
206     public void setRawByte(int addr, byte theData) {
207         dataSegments[addr / segmentSize].setByteAtPos(addr % segmentSize, theData);
208     }
209 
210     /**
211      * DOCUMENT ME!
212      *
213      * @param segmentSize DOCUMENT ME!
214      */
215     public void setSegmentSize(int segmentSize) {
216         this.segmentSize = segmentSize;
217         dataSegments = new DataBlock[0x010000 / segmentSize];
218     }
219 
220     /**
221      * DOCUMENT ME!
222      *
223      * @return DOCUMENT ME!
224      */
225     @Override
226     public String toString() {
227         StringBuilder sb = new StringBuilder();
228 
229         for (int i = 0; i < dataSegments.length; i++) {
230             if (dataSegments[i] != null) {
231                 dataSegments[i].writeTo(sb, i == 0);
232             }
233         }
234 
235         return sb.toString();
236     }
237 }