fprime-gds 4.0.0a9__py3-none-any.whl → 4.0.0a10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -194,6 +194,7 @@ class QualifiedType(BaseModel):
194
194
  class StructMember(BaseModel):
195
195
  type: Union[IntegerType, FloatType, BoolType, StringType, QualifiedType]
196
196
  size: int = 1
197
+ index: int
197
198
 
198
199
  class StructType(BaseModel):
199
200
  kind: str
@@ -209,7 +210,7 @@ class StructType(BaseModel):
209
210
  class AliasType(BaseModel):
210
211
  kind: str
211
212
  qualifiedName: str
212
- type: Union[AliasType, StructType, ArrayType, IntegerType, FloatType, QualifiedType, StringType]
213
+ type: Union[AliasType, StructType, ArrayType, IntegerType, BoolType, FloatType, StringType, QualifiedType]
213
214
  underlyingType: Union[StructType, ArrayType, IntegerType, BoolType, FloatType, StringType, QualifiedType]
214
215
 
215
216
  @field_validator('kind')
@@ -222,7 +223,7 @@ class ArrayType(BaseModel):
222
223
  kind: str
223
224
  qualifiedName: str
224
225
  size: int
225
- elementType: Union[AliasType, StructType, ArrayType, IntegerType, FloatType, QualifiedType, StringType]
226
+ elementType: Union[AliasType, StructType, ArrayType, IntegerType, BoolType, FloatType, StringType, QualifiedType]
226
227
 
227
228
  @field_validator('kind')
228
229
  def kind_qualifiedIdentifier(cls, v):
@@ -297,29 +298,33 @@ class DPHeader(BaseModel):
297
298
  @computed_field
298
299
  @property
299
300
  def header(self) -> Dict[str, Union[Type, ArrayType, EnumType]]:
300
- # All types/constants that make up the DP header
301
- header_dict = {
302
- "FwPacketDescriptorType": None,
303
- "FwDpIdType": None,
304
- "FwDpPriorityType" : None,
305
- "Seconds": None,
306
- "USeconds": None,
307
- "FwTimeBaseStoreType": None,
308
- "FwTimeContextStoreType": None,
309
- "Fw.DpCfg.ProcType": None,
310
- "Fw.DpCfg.CONTAINER_USER_DATA_SIZE": None,
311
- "Fw.DpState": None,
312
- "FwSizeStoreType": None
301
+ # Mapping from type/constant names to header field names
302
+ header_field_names = {
303
+ "FwPacketDescriptorType": "PacketDescriptor",
304
+ "FwDpIdType": "Id",
305
+ "FwDpPriorityType" : "Priority",
306
+ "Seconds": "Seconds",
307
+ "USeconds": "USeconds",
308
+ "FwTimeBaseStoreType": "TimeBase",
309
+ "FwTimeContextStoreType": "Context",
310
+ "Fw.DpCfg.ProcType": "ProcTypes",
311
+ "Fw.DpCfg.CONTAINER_USER_DATA_SIZE": "UserData",
312
+ "Fw.DpState": "DpState",
313
+ "FwSizeStoreType": "DataSize"
313
314
  }
314
- for k in header_dict.keys():
315
+ # All types/constants that make up the DP header
316
+ # Key: Values of above header_field_names
317
+ # Values: Initialized to None, populated below based on type names/constants in the JSON dictionary
318
+ header_dict = {v: None for v in header_field_names.values()}
319
+ for k, v in header_field_names.items():
315
320
  # Seconds and USeconds are not in the dictionary, but are both always U32
316
321
  if k == "Seconds" or k == "USeconds":
317
- header_dict[k] = Type(type=IntegerType(name="U32", kind="integer", size=32, signed=False))
322
+ header_dict[v] = Type(type=IntegerType(name="U32", kind="integer", size=32, signed=False))
318
323
  # According to Fw.Dp SDD, Header::UserData is an array of U8 of size Fw::DpCfg::CONTAINER_USER_DATA_SIZE.
319
324
  elif k == "Fw.DpCfg.CONTAINER_USER_DATA_SIZE":
320
325
  for t in self.constants:
321
326
  if t.qualifiedName == k:
322
- header_dict[k] = ArrayType(
327
+ header_dict[v] = ArrayType(
323
328
  kind="array",
324
329
  qualifiedName="UserData",
325
330
  size=t.value,
@@ -329,7 +334,7 @@ class DPHeader(BaseModel):
329
334
  else:
330
335
  for t in self.typeDefinitions:
331
336
  if t.qualifiedName == k:
332
- header_dict[k] = t
337
+ header_dict[v] = t
333
338
  break
334
339
 
335
340
  return header_dict
@@ -337,12 +342,15 @@ class DPHeader(BaseModel):
337
342
  @computed_field
338
343
  @property
339
344
  def dataId(self) -> AliasType:
340
- return self.header.get("FwDpIdType")
345
+ return self.header.get("Id")
341
346
 
342
347
  @computed_field
343
348
  @property
344
349
  def dataSize(self) -> AliasType:
345
- return self.header.get("FwSizeStoreType")
350
+ return self.header.get("DataSize")
351
+
352
+ def get_size_store_bytes(self) -> int:
353
+ return self.header.get("DataSize").underlyingType.size // 8
346
354
 
347
355
  @model_validator(mode='after')
348
356
  def validate_header(self) -> 'DPHeader':
@@ -371,7 +379,8 @@ type_mapping = {
371
379
  'U64': 'Q', # Unsigned 64-bit integer
372
380
  'F32': 'f', # 32-bit float
373
381
  'F64': 'd', # 64-bit float
374
- 'bool': '?' # An 8 bit boolean
382
+ 'bool': '?', # An 8 bit boolean
383
+ 'string': 's'
375
384
  # Add more mappings as needed
376
385
  }
377
386
 
@@ -485,6 +494,7 @@ class DataProductWriter:
485
494
  self.binaryFileName = binaryFileName
486
495
  self.totalBytesRead = 0
487
496
  self.calculatedCRC = 0
497
+ self.headerJSON = None
488
498
 
489
499
 
490
500
  # ----------------------------------------------------------------------------------------------
@@ -520,8 +530,29 @@ class DataProductWriter:
520
530
  except KeyError:
521
531
  raise KeyError(f"Unrecognized JSON Dictionary Type: {intType}")
522
532
  data = struct.unpack(format_str, bytes_read)[0]
533
+ return data
534
+
535
+ def read_and_deserialize_string(self) -> str:
536
+ size_store_type_bytes = self.headerJSON.get_size_store_bytes()
537
+ bytes_read_store = self.binaryFile.read(size_store_type_bytes)
538
+ if len(bytes_read_store) != size_store_type_bytes:
539
+ raise IOError(f"Tried to read {size_store_type_bytes} bytes from the binary file, but failed.")
540
+
541
+ self.totalBytesRead += size_store_type_bytes
542
+
543
+ format_str = f'{BIG_ENDIAN}H'
544
+ string_size_data = struct.unpack(format_str, bytes_read_store)[0]
545
+
546
+ bytes_read = self.binaryFile.read(string_size_data)
547
+ if len(bytes_read) != string_size_data:
548
+ raise IOError(f"Tried to read {string_size_data} bytes from the binary file, but failed.")
523
549
 
550
+ self.calculatedCRC = crc32(bytes_read_store + bytes_read, self.calculatedCRC) & 0xffffffff
551
+ self.totalBytesRead += string_size_data
524
552
 
553
+ format_str = f'{BIG_ENDIAN}{string_size_data}s'
554
+ data = struct.unpack(format_str, bytes_read)[0]
555
+ data = data.decode()
525
556
  return data
526
557
 
527
558
  # -----------------------------------------------------------------------------------------------------------------------
@@ -568,7 +599,7 @@ class DataProductWriter:
568
599
  # AssertionError: If the field_config is not an IntegerType, FloatType, or BoolType.
569
600
  # -----------------------------------------------------------------------------------------------------------------------
570
601
 
571
- def read_field(self, field_config: Union[IntegerType, FloatType, BoolType]) -> Union[int, float, bool]:
602
+ def read_field(self, field_config: Union[IntegerType, FloatType, BoolType, StringType]) -> Union[int, float, bool]:
572
603
 
573
604
  if type(field_config) is IntegerType:
574
605
  sizeBytes = field_config.size // 8
@@ -579,6 +610,9 @@ class DataProductWriter:
579
610
  elif type(field_config) is BoolType:
580
611
  sizeBytes = field_config.size // 8
581
612
 
613
+ elif type(field_config) is StringType:
614
+ return self.read_and_deserialize_string()
615
+
582
616
  else:
583
617
  assert False, "Unsupported typeKind encountered"
584
618
 
@@ -626,6 +660,8 @@ class DataProductWriter:
626
660
  elif isinstance(typeKind, BoolType):
627
661
  parent_dict[field_name] = self.read_field(typeKind)
628
662
 
663
+ elif isinstance(typeKind, StringType):
664
+ parent_dict[field_name] = self.read_field(typeKind)
629
665
 
630
666
  elif isinstance(typeKind, EnumType):
631
667
  value = self.read_field(typeKind.representationType)
@@ -646,7 +682,8 @@ class DataProductWriter:
646
682
 
647
683
  elif isinstance(typeKind, StructType):
648
684
  array_list = []
649
- for key, member in typeKind.members.items():
685
+ sorted_members = dict(sorted(typeKind.members.items(), key=lambda member: member[1].index))
686
+ for key, member in sorted_members.items():
650
687
  for i in range(member.size):
651
688
  element_dict = {}
652
689
  self.get_struct_item(key, member.type, typeList, element_dict)
@@ -830,7 +867,7 @@ class DataProductWriter:
830
867
  header_json["typeDefinitions"] = dict_json["typeDefinitions"]
831
868
  if "constants" in dict_json:
832
869
  header_json["constants"] = dict_json["constants"]
833
- headerJSON = DPHeader(**header_json)
870
+ self.headerJSON = DPHeader(**header_json)
834
871
 
835
872
  except json.JSONDecodeError as e:
836
873
  raise DictionaryError(self.jsonDict, e.lineno)
@@ -840,10 +877,10 @@ class DataProductWriter:
840
877
  with open(self.binaryFileName, 'rb') as self.binaryFile:
841
878
 
842
879
  # Read the header data up until the Records
843
- headerData = self.get_header_info(headerJSON)
880
+ headerData = self.get_header_info(self.headerJSON)
844
881
 
845
882
  # Read the total data size
846
- dataSize = headerData['FwSizeStoreType']
883
+ dataSize = headerData['DataSize']
847
884
 
848
885
  # Restart the count of bytes read
849
886
  self.totalBytesRead = 0
@@ -851,13 +888,12 @@ class DataProductWriter:
851
888
  recordList = [headerData]
852
889
 
853
890
  while self.totalBytesRead < dataSize:
854
-
855
- recordData = self.get_record_data(headerJSON, dictJSON)
891
+ recordData = self.get_record_data(self.headerJSON, dictJSON)
856
892
  recordList.append(recordData)
857
893
 
858
894
  computedCRC = self.calculatedCRC
859
895
  # Read the data checksum
860
- headerData['dataHash'] = self.read_field(headerJSON.dataHash.type)
896
+ headerData['dataHash'] = self.read_field(self.headerJSON.dataHash.type)
861
897
 
862
898
  if computedCRC != headerData['dataHash']:
863
899
  raise CRCError("Data", headerData['dataHash'], computedCRC)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fprime-gds
3
- Version: 4.0.0a9
3
+ Version: 4.0.0a10
4
4
  Summary: F Prime Flight Software Ground Data System layer
5
5
  Author-email: Michael Starch <Michael.D.Starch@jpl.nasa.gov>, Thomas Boyer-Chammard <Thomas.Boyer.Chammard@jpl.nasa.gov>
6
6
  License:
@@ -125,7 +125,7 @@ fprime_gds/executables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
125
125
  fprime_gds/executables/apps.py,sha256=u79T_PlgMmNmA4YwWjs7LvPMCJnrjnURr05NMthOYP0,13350
126
126
  fprime_gds/executables/cli.py,sha256=Qqq3JQOqTsfDRsbTALw25xnwN7fCEVlpcKDV4jvGopQ,50961
127
127
  fprime_gds/executables/comm.py,sha256=08rO0o0MJgTRngB7Ygu2IL_gEAWKF7WFvFyro1CqReE,5214
128
- fprime_gds/executables/data_product_writer.py,sha256=PGNju52vjfg7-AUURFojmMV8S83Tzy58Hyti5tmpffc,35821
128
+ fprime_gds/executables/data_product_writer.py,sha256=e1Rp2LT_Cpg08f0Ki8GhirC7Wn6LtYiAef7KLAkZHUY,37773
129
129
  fprime_gds/executables/fprime_cli.py,sha256=CMoT7zWNwM8h2mSZW03AR96wl_XnZXoLNiOZN_sDi38,12431
130
130
  fprime_gds/executables/run_deployment.py,sha256=Zl0Y9-6i6c8tZhcS7XkAeVQtzn0d9fV-3UJQZ0bnBrc,7237
131
131
  fprime_gds/executables/tcpserver.py,sha256=KspVpu5YIuiWKOk5E6UDMKvqXYrRB1j9aX8CkMxysfw,17555
@@ -244,10 +244,10 @@ fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff2,sha256=mDS4KtJuK
244
244
  fprime_gds/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
245
  fprime_gds/plugin/definitions.py,sha256=QlxW1gNvoiqGMslSJjh3dTFZuv0igFHawN__3XJ0Wns,5355
246
246
  fprime_gds/plugin/system.py,sha256=M9xb-8jBhCUUx3X1z2uAP8Wx_v6NkL8JeaFgGcMnQqY,13432
247
- fprime_gds-4.0.0a9.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
248
- fprime_gds-4.0.0a9.dist-info/licenses/NOTICE.txt,sha256=vXjA_xRcQhd83Vfk5D_vXg5kOjnnXvLuMi5vFKDEVmg,1612
249
- fprime_gds-4.0.0a9.dist-info/METADATA,sha256=v5sVN1vOTmpwQbZTJxg2OsJnbUFPEasPQ_AJjQvLweg,24576
250
- fprime_gds-4.0.0a9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
251
- fprime_gds-4.0.0a9.dist-info/entry_points.txt,sha256=V2XMHMUJUGTVx5s3_kK1jLmoxSKE1vvj2XWHH9y49WQ,423
252
- fprime_gds-4.0.0a9.dist-info/top_level.txt,sha256=6vzFLIX6ANfavKaXFHDMSLFtS94a6FaAsIWhjgYuSNE,27
253
- fprime_gds-4.0.0a9.dist-info/RECORD,,
247
+ fprime_gds-4.0.0a10.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
248
+ fprime_gds-4.0.0a10.dist-info/licenses/NOTICE.txt,sha256=vXjA_xRcQhd83Vfk5D_vXg5kOjnnXvLuMi5vFKDEVmg,1612
249
+ fprime_gds-4.0.0a10.dist-info/METADATA,sha256=zD-VViHWpGeATD0SzBD1-yKMFOR25JIEIM3uBqMlY5Q,24577
250
+ fprime_gds-4.0.0a10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
251
+ fprime_gds-4.0.0a10.dist-info/entry_points.txt,sha256=V2XMHMUJUGTVx5s3_kK1jLmoxSKE1vvj2XWHH9y49WQ,423
252
+ fprime_gds-4.0.0a10.dist-info/top_level.txt,sha256=6vzFLIX6ANfavKaXFHDMSLFtS94a6FaAsIWhjgYuSNE,27
253
+ fprime_gds-4.0.0a10.dist-info/RECORD,,