@@ -90,6 +90,7 @@ type DataObject struct {
9090 Points []Point `json:"points"`
9191 Extra []byte `json:"extra,omitempty"`
9292 totalSize int
93+ indexes []int
9394}
9495
9596func (do * DataObject ) FromBytes (data []byte ) error {
@@ -114,16 +115,26 @@ func (do *DataObject) FromBytes(data []byte) error {
114115 return nil
115116 }
116117
117- var sizeAllPoints int
118+ var size int
118119
119- do .Points , sizeAllPoints , err = do .Header .objectType .Constructor (
120+ do .Points , size , err = do .Header .objectType .Constructor (
120121 data [headSize :],
121122 numPoints ,
122123 do .Header .PointPrefixCode .GetPointPrefixSize (),
124+ do .Header .PointPrefixCode ,
123125 )
124- do .totalSize += sizeAllPoints
126+ if err != nil {
127+ return fmt .Errorf ("can't create points: %w" , err )
128+ }
129+
130+ do .totalSize += size
131+
132+ err = do .updateIndexes ()
133+ if err != nil {
134+ return fmt .Errorf ("failed to update indexes: %w" , err )
135+ }
125136
126- return err
137+ return nil
127138}
128139
129140func (do * DataObject ) ToBytes () ([]byte , error ) {
@@ -201,6 +212,95 @@ func (do *DataObject) SizeOf() int {
201212 return do .totalSize
202213}
203214
215+ func (do * DataObject ) Indexes () []int {
216+ return do .indexes
217+ }
218+
219+ //nolint:cyclop // straightforward switches
220+ func (do * DataObject ) updateIndexes () error {
221+ switch rangeField := do .Header .RangeField .(type ) {
222+ // If the RangeField has start and stop indexes, we can pull those (0 - 5)
223+ case * RangeField0 :
224+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
225+ do .indexes = append (do .indexes , int (i ))
226+ }
227+
228+ return nil
229+ case * RangeField1 :
230+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
231+ do .indexes = append (do .indexes , int (i ))
232+ }
233+
234+ return nil
235+ case * RangeField2 :
236+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
237+ do .indexes = append (do .indexes , int (i ))
238+ }
239+
240+ return nil
241+ case * RangeField3 :
242+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
243+ do .indexes = append (do .indexes , int (i ))
244+ }
245+
246+ return nil
247+ case * RangeField4 :
248+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
249+ do .indexes = append (do .indexes , int (i ))
250+ }
251+
252+ return nil
253+ case * RangeField5 :
254+ for i := rangeField .Start ; i <= rangeField .Stop ; i ++ {
255+ do .indexes = append (do .indexes , int (i ))
256+ }
257+
258+ return nil
259+ // TODO - assumption
260+ // If the RangeField is all, we expect the points start at 0
261+ case * RangeField6 :
262+ for i := range len (do .Points ) {
263+ do .indexes = append (do .indexes , i )
264+ }
265+
266+ return nil
267+ // If the RangeField is count-based, we need to pull the indexes from the points themselves
268+ case * RangeField7 , * RangeField8 , * RangeField9 , * RangeFieldB :
269+ return do .updateIndexesFromPrefix ()
270+ default :
271+ return fmt .Errorf ("unexpected range field type %T" , do .Header .RangeField )
272+ }
273+ }
274+
275+ // updateIndexesFromPrefix resolves point indexes for count-based range
276+ // fields by inspecting the object header's PointPrefixCode.
277+ func (do * DataObject ) updateIndexesFromPrefix () error {
278+ switch do .Header .PointPrefixCode {
279+ case OctetIndex1 , OctetIndex2 , OctetIndex4 :
280+ for _ , point := range do .Points {
281+ index , err := point .GetIndex ()
282+ if err != nil {
283+ return fmt .Errorf ("failed to get index from point: %w" , err )
284+ }
285+
286+ do .indexes = append (do .indexes , index )
287+ }
288+
289+ return nil
290+ case NoPrefix :
291+ for i := range do .Points {
292+ do .indexes = append (do .indexes , i )
293+ }
294+
295+ return nil
296+ default :
297+ return fmt .Errorf (
298+ "cannot determine point indexes for prefix code %s" ,
299+ do .Header .PointPrefixCode ,
300+ )
301+ }
302+ }
303+
204304// ObjectHeader is used to describe the structure of application data.
205305type ObjectHeader struct {
206306 // Object Type Field
@@ -219,16 +319,16 @@ type rangeFieldConstructor func() RangeField
219319
220320var rangeFieldConstructors = map [RangeSpecCode ]rangeFieldConstructor {
221321 StartStop1 : func () RangeField { return & RangeField0 {} },
222- VirtualStartStop1 : func () RangeField { return & RangeField0 {} },
223322 StartStop2 : func () RangeField { return & RangeField1 {} },
224- VirtualStartStop2 : func () RangeField { return & RangeField1 {} },
225323 StartStop4 : func () RangeField { return & RangeField2 {} },
226- VirtualStartStop4 : func () RangeField { return & RangeField2 {} },
324+ VirtualStartStop1 : func () RangeField { return & RangeField3 {} },
325+ VirtualStartStop2 : func () RangeField { return & RangeField4 {} },
326+ VirtualStartStop4 : func () RangeField { return & RangeField5 {} },
227327 NoRangeField : func () RangeField { return & RangeField6 {} },
228328 Count1 : func () RangeField { return & RangeField7 {} },
229- Count1Variable : func () RangeField { return & RangeField7 {} },
230329 Count2 : func () RangeField { return & RangeField8 {} },
231330 Count4 : func () RangeField { return & RangeField9 {} },
331+ Count1Variable : func () RangeField { return & RangeFieldB {} },
232332}
233333
234334var reservedRangeSpecifiers = map [RangeSpecCode ]struct {}{
0 commit comments