rustorb 0.1.1__tar.gz → 0.3.0__tar.gz

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.
Files changed (138) hide show
  1. {rustorb-0.1.1 → rustorb-0.3.0}/Cargo.lock +44 -15
  2. {rustorb-0.1.1 → rustorb-0.3.0}/Cargo.toml +6 -5
  3. {rustorb-0.1.1 → rustorb-0.3.0}/PKG-INFO +2 -2
  4. {rustorb-0.1.1 → rustorb-0.3.0}/README.md +1 -1
  5. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/decoder.rs +57 -24
  6. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/encoder.rs +123 -29
  7. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/error.rs +8 -2
  8. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/lib.rs +35 -3
  9. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/value.rs +5 -3
  10. rustorb-0.3.0/crates/rustorb-cdr/src/xcdr.rs +685 -0
  11. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/tests/cdr.rs +49 -5
  12. rustorb-0.3.0/crates/rustorb-cdr/tests/xcdr.rs +578 -0
  13. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/Cargo.toml +1 -0
  14. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/benches/throughput.rs +40 -2
  15. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/codeset.rs +7 -0
  16. rustorb-0.3.0/crates/rustorb-core/src/connection.rs +785 -0
  17. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/dii.rs +56 -13
  18. rustorb-0.3.0/crates/rustorb-core/src/idl/abstract_iface.rs +153 -0
  19. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/idl/mod.rs +10 -5
  20. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/idl/tests.rs +5 -5
  21. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/idl/value.rs +53 -34
  22. rustorb-0.3.0/crates/rustorb-core/src/idle.rs +47 -0
  23. rustorb-0.3.0/crates/rustorb-core/src/iop.rs +202 -0
  24. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/lib.rs +12 -3
  25. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/object.rs +441 -53
  26. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/orb.rs +353 -23
  27. rustorb-0.3.0/crates/rustorb-core/src/pi.rs +1869 -0
  28. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/poa.rs +69 -17
  29. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/policy.rs +73 -16
  30. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/servant.rs +83 -5
  31. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/server.rs +830 -60
  32. rustorb-0.3.0/crates/rustorb-core/src/trace.rs +290 -0
  33. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/typecode/cdr.rs +5 -1
  34. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/typecode/tests.rs +8 -8
  35. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/wire.rs +43 -1
  36. rustorb-0.3.0/crates/rustorb-core/tests/bidir.rs +487 -0
  37. rustorb-0.3.0/crates/rustorb-core/tests/connections.rs +379 -0
  38. rustorb-0.3.0/crates/rustorb-core/tests/message_size.rs +203 -0
  39. rustorb-0.3.0/crates/rustorb-core/tests/pi.rs +1221 -0
  40. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls.rs +26 -0
  41. rustorb-0.3.0/crates/rustorb-core/tests/trace.rs +223 -0
  42. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/valuetype.rs +7 -7
  43. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/component.rs +3 -3
  44. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/header.rs +5 -5
  45. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/iiop.rs +5 -5
  46. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/ior.rs +3 -3
  47. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/lib.rs +3 -1
  48. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/message.rs +3 -3
  49. rustorb-0.3.0/crates/rustorb-giop/src/service_context.rs +229 -0
  50. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/writer.rs +221 -1
  51. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/tests/giop.rs +196 -0
  52. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/tests/omniorb_golden.rs +3 -3
  53. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/Cargo.toml +1 -0
  54. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/lib.rs +14 -0
  55. rustorb-0.3.0/crates/rustorb-python/src/log.rs +193 -0
  56. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/orb.rs +47 -10
  57. rustorb-0.3.0/crates/rustorb-python/src/pi.rs +997 -0
  58. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/poa.rs +7 -5
  59. {rustorb-0.1.1 → rustorb-0.3.0}/pyproject.toml +1 -1
  60. rustorb-0.3.0/rustorb/BiDirPolicy.py +38 -0
  61. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/CORBA.py +23 -1
  62. rustorb-0.3.0/rustorb/IOP.py +140 -0
  63. rustorb-0.3.0/rustorb/PortableInterceptor.py +487 -0
  64. rustorb-0.3.0/rustorb/__init__.py +31 -0
  65. rustorb-0.3.0/rustorb/_log.py +87 -0
  66. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/_native.pyi +108 -1
  67. rustorb-0.1.1/crates/rustorb-core/src/connection.rs +0 -434
  68. rustorb-0.1.1/crates/rustorb-giop/src/service_context.rs +0 -116
  69. rustorb-0.1.1/rustorb/__init__.py +0 -12
  70. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/Cargo.toml +0 -0
  71. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/LICENSE-APACHE +0 -0
  72. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/LICENSE-MIT +0 -0
  73. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/README.md +0 -0
  74. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/long_double.rs +0 -0
  75. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/octets.rs +0 -0
  76. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-cdr/src/traits.rs +0 -0
  77. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/LICENSE-APACHE +0 -0
  78. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/LICENSE-MIT +0 -0
  79. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/README.md +0 -0
  80. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/dynany/mod.rs +0 -0
  81. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/dynany/tests.rs +0 -0
  82. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/exception.rs +0 -0
  83. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/fixed.rs +0 -0
  84. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/name.rs +0 -0
  85. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/pool.rs +0 -0
  86. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/stream.rs +0 -0
  87. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/timeout.rs +0 -0
  88. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/tls.rs +0 -0
  89. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/typecode/mod.rs +0 -0
  90. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/src/value.rs +0 -0
  91. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/any.rs +0 -0
  92. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/async_api.rs +0 -0
  93. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/client.rs +0 -0
  94. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/dii.rs +0 -0
  95. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/poa.rs +0 -0
  96. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/policy.rs +0 -0
  97. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/server.rs +0 -0
  98. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/soak.rs +0 -0
  99. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/stress.rs +0 -0
  100. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/ca.pem +0 -0
  101. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/client-bundle.pem +0 -0
  102. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/client.key +0 -0
  103. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/client.pem +0 -0
  104. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/make-certs.sh +0 -0
  105. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/other-ca.pem +0 -0
  106. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/other-server.key +0 -0
  107. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/other-server.pem +0 -0
  108. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/server-bundle.pem +0 -0
  109. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/server.key +0 -0
  110. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/server.pem +0 -0
  111. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/wrong-name.key +0 -0
  112. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-core/tests/tls/wrong-name.pem +0 -0
  113. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/Cargo.toml +0 -0
  114. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/LICENSE-APACHE +0 -0
  115. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/LICENSE-MIT +0 -0
  116. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/README.md +0 -0
  117. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/corbaloc.rs +0 -0
  118. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/error.rs +0 -0
  119. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/src/fragment.rs +0 -0
  120. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-giop/tests/ior.rs +0 -0
  121. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/LICENSE-APACHE +0 -0
  122. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/LICENSE-MIT +0 -0
  123. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/README.md +0 -0
  124. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/build.rs +0 -0
  125. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/any.rs +0 -0
  126. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/dii.rs +0 -0
  127. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/dynany.rs +0 -0
  128. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/error.rs +0 -0
  129. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/tc.rs +0 -0
  130. {rustorb-0.1.1 → rustorb-0.3.0}/crates/rustorb-python/src/value.rs +0 -0
  131. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/DynamicAny.py +0 -0
  132. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/Messaging.py +0 -0
  133. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/PortableServer.py +0 -0
  134. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/PortableServer__POA.py +0 -0
  135. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/TimeBase.py +0 -0
  136. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/_rt.py +0 -0
  137. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/_types.py +0 -0
  138. {rustorb-0.1.1 → rustorb-0.3.0}/rustorb/timeouts.py +0 -0
@@ -438,19 +438,11 @@ dependencies = [
438
438
 
439
439
  [[package]]
440
440
  name = "rustorb-cdr"
441
- version = "0.1.1"
442
-
443
- [[package]]
444
- name = "rustorb-codegen"
445
- version = "0.1.1"
446
- dependencies = [
447
- "rustorb-core",
448
- "tokio",
449
- ]
441
+ version = "0.3.0"
450
442
 
451
443
  [[package]]
452
444
  name = "rustorb-core"
453
- version = "0.1.1"
445
+ version = "0.3.0"
454
446
  dependencies = [
455
447
  "criterion",
456
448
  "libc",
@@ -459,12 +451,13 @@ dependencies = [
459
451
  "rustorb-giop",
460
452
  "socket2",
461
453
  "tokio",
454
+ "tracing",
462
455
  "windows-sys 0.61.2",
463
456
  ]
464
457
 
465
458
  [[package]]
466
459
  name = "rustorb-ffi"
467
- version = "0.1.1"
460
+ version = "0.3.0"
468
461
  dependencies = [
469
462
  "rustorb-cdr",
470
463
  "rustorb-core",
@@ -472,7 +465,7 @@ dependencies = [
472
465
 
473
466
  [[package]]
474
467
  name = "rustorb-giop"
475
- version = "0.1.1"
468
+ version = "0.3.0"
476
469
  dependencies = [
477
470
  "rustorb-cdr",
478
471
  "serde_json",
@@ -480,26 +473,43 @@ dependencies = [
480
473
 
481
474
  [[package]]
482
475
  name = "rustorb-interop"
483
- version = "0.1.1"
476
+ version = "0.3.0"
484
477
  dependencies = [
485
478
  "rustorb-core",
486
479
  "rustorb-naming",
487
480
  ]
488
481
 
482
+ [[package]]
483
+ name = "rustorb-mapping-tests"
484
+ version = "0.0.0"
485
+ dependencies = [
486
+ "rustorb-core",
487
+ "rustorb-typesupport",
488
+ "tokio",
489
+ ]
490
+
489
491
  [[package]]
490
492
  name = "rustorb-naming"
491
- version = "0.1.1"
493
+ version = "0.3.0"
492
494
  dependencies = [
493
495
  "rustorb-core",
494
496
  ]
495
497
 
496
498
  [[package]]
497
499
  name = "rustorb-python"
498
- version = "0.1.1"
500
+ version = "0.3.0"
499
501
  dependencies = [
500
502
  "pyo3",
501
503
  "pyo3-build-config",
502
504
  "rustorb-core",
505
+ "tracing",
506
+ ]
507
+
508
+ [[package]]
509
+ name = "rustorb-typesupport"
510
+ version = "0.3.0"
511
+ dependencies = [
512
+ "rustorb-cdr",
503
513
  ]
504
514
 
505
515
  [[package]]
@@ -628,6 +638,25 @@ dependencies = [
628
638
  "windows-sys 0.61.2",
629
639
  ]
630
640
 
641
+ [[package]]
642
+ name = "tracing"
643
+ version = "0.1.44"
644
+ source = "registry+https://github.com/rust-lang/crates.io-index"
645
+ checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
646
+ dependencies = [
647
+ "pin-project-lite",
648
+ "tracing-core",
649
+ ]
650
+
651
+ [[package]]
652
+ name = "tracing-core"
653
+ version = "0.1.36"
654
+ source = "registry+https://github.com/rust-lang/crates.io-index"
655
+ checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
656
+ dependencies = [
657
+ "once_cell",
658
+ ]
659
+
631
660
  [[package]]
632
661
  name = "unicode-ident"
633
662
  version = "1.0.27"
@@ -3,7 +3,7 @@ resolver = "3"
3
3
  members = ["crates/rustorb-cdr", "crates/rustorb-giop", "crates/rustorb-core", "crates/rustorb-python"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.1.1"
6
+ version = "0.3.0"
7
7
  edition = "2024"
8
8
  rust-version = "1.85"
9
9
  license = "MIT OR Apache-2.0"
@@ -13,10 +13,11 @@ keywords = ["corba", "giop", "iiop", "orb", "rpc"]
13
13
  categories = ["network-programming"]
14
14
 
15
15
  [workspace.dependencies]
16
- rustorb-cdr = { path = "crates/rustorb-cdr", version = "0.1.1" }
17
- rustorb-giop = { path = "crates/rustorb-giop", version = "0.1.1" }
18
- rustorb-core = { path = "crates/rustorb-core", version = "0.1.1" }
19
- rustorb-naming = { path = "crates/rustorb-naming", version = "0.1.1" }
16
+ rustorb-cdr = { path = "crates/rustorb-cdr", version = "0.3.0" }
17
+ rustorb-typesupport = { path = "crates/rustorb-typesupport", version = "0.3.0" }
18
+ rustorb-giop = { path = "crates/rustorb-giop", version = "0.3.0" }
19
+ rustorb-core = { path = "crates/rustorb-core", version = "0.3.0" }
20
+ rustorb-naming = { path = "crates/rustorb-naming", version = "0.3.0" }
20
21
  tokio = { version = "1", default-features = false }
21
22
 
22
23
  [workspace.lints.rust]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rustorb
3
- Version: 0.1.1
3
+ Version: 0.3.0
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Topic :: System :: Networking
6
6
  Classifier: Topic :: Software Development :: Object Brokering
@@ -44,7 +44,7 @@ orb.destroy()
44
44
 
45
45
  The wheels are abi3, for CPython 3.9 or later, with the ORB core compiled
46
46
  in: GIOP 1.0–1.2, IIOP and SSLIOP, the POA, Any / TypeCode / DynAny,
47
- valuetypes, DII / DSI and call timeouts. See the
47
+ valuetypes, DII / DSI, Portable Interceptors and call timeouts. See the
48
48
  [getting started guide](https://github.com/rustorb/rustorb/blob/main/docs/getting-started.md).
49
49
 
50
50
  Licensed under MIT OR Apache-2.0.
@@ -29,7 +29,7 @@ orb.destroy()
29
29
 
30
30
  The wheels are abi3, for CPython 3.9 or later, with the ORB core compiled
31
31
  in: GIOP 1.0–1.2, IIOP and SSLIOP, the POA, Any / TypeCode / DynAny,
32
- valuetypes, DII / DSI and call timeouts. See the
32
+ valuetypes, DII / DSI, Portable Interceptors and call timeouts. See the
33
33
  [getting started guide](https://github.com/rustorb/rustorb/blob/main/docs/getting-started.md).
34
34
 
35
35
  Licensed under MIT OR Apache-2.0.
@@ -1,6 +1,6 @@
1
1
  use std::sync::Arc;
2
2
 
3
- use crate::{ByteOrder, CdrVersion, Error, LongDouble, Octets, Result, SHARE_MIN};
3
+ use crate::{ByteOrder, Encoding, Error, LongDouble, Octets, Result, SHARE_MIN};
4
4
 
5
5
  /// Reads CDR from a byte slice.
6
6
  ///
@@ -15,8 +15,10 @@ pub struct Decoder<'a> {
15
15
  shared: Option<&'a Arc<Vec<u8>>>,
16
16
  pub(crate) pos: usize,
17
17
  pub(crate) order: ByteOrder,
18
- version: CdrVersion,
18
+ encoding: Encoding,
19
19
  base: usize,
20
+ /// The stream offset alignment counts from (`XCDR.origin`).
21
+ pub(crate) origin: usize,
20
22
  segments: &'a [Segment],
21
23
  wstring_default_order: ByteOrder,
22
24
  /// What the valuetypes read so far need (indirections, chunks);
@@ -56,15 +58,15 @@ macro_rules! read_number {
56
58
 
57
59
  impl<'a> Decoder<'a> {
58
60
  /// Creates a decoder whose first byte is at stream offset 0.
59
- pub fn new(buf: &'a [u8], order: ByteOrder, version: CdrVersion) -> Decoder<'a> {
60
- Decoder::with_offset(buf, order, version, 0)
61
+ pub fn new(buf: &'a [u8], order: ByteOrder, encoding: Encoding) -> Decoder<'a> {
62
+ Decoder::with_offset(buf, order, encoding, 0)
61
63
  }
62
64
 
63
65
  /// Creates a decoder whose first byte is at stream offset `base`.
64
66
  pub fn with_offset(
65
67
  buf: &'a [u8],
66
68
  order: ByteOrder,
67
- version: CdrVersion,
69
+ encoding: Encoding,
68
70
  base: usize,
69
71
  ) -> Decoder<'a> {
70
72
  Decoder {
@@ -72,8 +74,9 @@ impl<'a> Decoder<'a> {
72
74
  shared: None,
73
75
  pos: 0,
74
76
  order,
75
- version,
77
+ encoding,
76
78
  base,
79
+ origin: 0,
77
80
  segments: &[],
78
81
  wstring_default_order: ByteOrder::Big,
79
82
  values: None,
@@ -90,10 +93,10 @@ impl<'a> Decoder<'a> {
90
93
 
91
94
  /// Opens an encapsulation: reads the byte order octet and returns a
92
95
  /// decoder positioned after it, with alignment starting at that octet.
93
- pub fn encapsulation(buf: &'a [u8], version: CdrVersion) -> Result<Decoder<'a>> {
96
+ pub fn encapsulation(buf: &'a [u8], encoding: Encoding) -> Result<Decoder<'a>> {
94
97
  let (&flag, _) = buf.split_first().ok_or(Error::EmptyEncapsulation)?;
95
98
  let order = ByteOrder::from_flag(flag)?;
96
- let mut dec = Decoder::new(buf, order, version);
99
+ let mut dec = Decoder::new(buf, order, encoding);
97
100
  dec.pos = 1;
98
101
  Ok(dec)
99
102
  }
@@ -110,9 +113,9 @@ impl<'a> Decoder<'a> {
110
113
  self.order
111
114
  }
112
115
 
113
- /// The GIOP version whose CDR rules apply.
114
- pub fn version(&self) -> CdrVersion {
115
- self.version
116
+ /// The encoding whose rules apply.
117
+ pub fn encoding(&self) -> Encoding {
118
+ self.encoding
116
119
  }
117
120
 
118
121
  /// The stream offset of the next byte.
@@ -142,14 +145,19 @@ impl<'a> Decoder<'a> {
142
145
  &self.buf[self.pos..]
143
146
  }
144
147
 
145
- /// Skips padding until the stream offset is a multiple of `align`.
148
+ /// Skips padding until the stream offset is a multiple of `align`, or
149
+ /// of the encoding's [`max_align`](Encoding::max_align) when that is
150
+ /// smaller.
146
151
  ///
147
152
  /// Inside a chunked valuetype, a chunk that ends here is followed by
148
- /// the next one: its length is read and the data aligned in it.
153
+ /// the next one: its length is read and the data aligned in it. In an
154
+ /// XCDR stream the offset counts from the alignment origin (see
155
+ /// [`set_origin`](Decoder::set_origin)).
149
156
  pub fn align(&mut self, align: usize) -> Result<()> {
157
+ let align = align.min(self.encoding.max_align());
150
158
  loop {
151
159
  self.chunk_boundary()?;
152
- let rem = self.position() % align;
160
+ let rem = self.position().wrapping_sub(self.origin) % align;
153
161
  if rem == 0 {
154
162
  return Ok(());
155
163
  }
@@ -163,6 +171,19 @@ impl<'a> Decoder<'a> {
163
171
  }
164
172
  }
165
173
 
174
+ /// The stream offset alignment counts from: 0 unless changed with
175
+ /// [`set_origin`](Decoder::set_origin).
176
+ pub fn origin(&self) -> usize {
177
+ self.origin
178
+ }
179
+
180
+ /// Makes alignment count from stream offset `origin`. This is the XCDR
181
+ /// `PUSH(ORIGIN)`; [`read_parameter`](Decoder::read_parameter) does it
182
+ /// itself.
183
+ pub fn set_origin(&mut self, origin: usize) {
184
+ self.origin = origin;
185
+ }
186
+
166
187
  /// Skips `n` bytes.
167
188
  pub fn skip(&mut self, n: usize) -> Result<()> {
168
189
  self.read_octets(n).map(|_| ())
@@ -341,10 +362,10 @@ impl<'a> Decoder<'a> {
341
362
 
342
363
  /// Reads a `wchar` holding one UTF-16 code unit.
343
364
  pub fn read_wchar(&mut self) -> Result<u16> {
344
- match self.version {
345
- CdrVersion::Giop1_0 => Err(Error::WcharNotSupported),
346
- CdrVersion::Giop1_1 => self.read_u16(),
347
- CdrVersion::Giop1_2 => {
365
+ match self.encoding {
366
+ Encoding::Giop1_0 => Err(Error::WcharNotSupported),
367
+ Encoding::Giop1_1 | Encoding::Xcdr1 | Encoding::Xcdr2 => self.read_u16(),
368
+ Encoding::Giop1_2 => {
348
369
  let len = self.read_octet()?;
349
370
  if len != 2 && len != 4 {
350
371
  return Err(Error::InvalidWcharLength(len));
@@ -362,11 +383,23 @@ impl<'a> Decoder<'a> {
362
383
  /// Reads a `wstring` encoded as UTF-16.
363
384
  ///
364
385
  /// For GIOP 1.2 a leading BOM selects the byte order; without one the
365
- /// order set by [`Decoder::set_wstring_default_order`] is used.
386
+ /// order set by [`Decoder::set_wstring_default_order`] is used. XCDR
387
+ /// has an octet length and code units in the stream byte order.
366
388
  pub fn read_wstring(&mut self) -> Result<String> {
367
- match self.version {
368
- CdrVersion::Giop1_0 => Err(Error::WcharNotSupported),
369
- CdrVersion::Giop1_1 => {
389
+ match self.encoding {
390
+ Encoding::Giop1_0 => Err(Error::WcharNotSupported),
391
+ Encoding::Xcdr1 | Encoding::Xcdr2 => {
392
+ let len = self.read_len(1)?;
393
+ if len % 2 != 0 {
394
+ return Err(Error::OddWstringLength(len as u32));
395
+ }
396
+ let mut units = Vec::with_capacity(len / 2);
397
+ for _ in 0..len / 2 {
398
+ units.push(self.read_u16()?);
399
+ }
400
+ String::from_utf16(&units).map_err(|_| Error::InvalidUtf16)
401
+ }
402
+ Encoding::Giop1_1 => {
370
403
  let len = self.read_len(2)?;
371
404
  let mut units = Vec::with_capacity(len);
372
405
  for _ in 0..len {
@@ -378,7 +411,7 @@ impl<'a> Decoder<'a> {
378
411
  }
379
412
  String::from_utf16(&units).map_err(|_| Error::InvalidUtf16)
380
413
  }
381
- CdrVersion::Giop1_2 => {
414
+ Encoding::Giop1_2 => {
382
415
  let bytes = self.read_octet_seq()?;
383
416
  if bytes.len() % 2 != 0 {
384
417
  return Err(Error::OddWstringLength(bytes.len() as u32));
@@ -407,7 +440,7 @@ impl<'a> Decoder<'a> {
407
440
  /// Reads an encapsulation and returns a decoder over its contents.
408
441
  pub fn read_encapsulation(&mut self) -> Result<Decoder<'a>> {
409
442
  let bytes = self.read_octet_seq()?;
410
- let mut inner = Decoder::encapsulation(bytes, self.version)?;
443
+ let mut inner = Decoder::encapsulation(bytes, self.encoding)?;
411
444
  inner.wstring_default_order = self.wstring_default_order;
412
445
  Ok(inner)
413
446
  }
@@ -1,4 +1,4 @@
1
- use crate::{ByteOrder, CdrVersion, Error, LongDouble, Octets, Result, SHARE_MIN};
1
+ use crate::{ByteOrder, Encoding, Error, LongDouble, Octets, Result, SHARE_MIN};
2
2
 
3
3
  /// Writes CDR into a growable buffer.
4
4
  ///
@@ -21,12 +21,21 @@ pub struct Encoder {
21
21
  shared_len: usize,
22
22
  allow_shared: bool,
23
23
  pub(crate) order: ByteOrder,
24
- version: CdrVersion,
24
+ encoding: Encoding,
25
25
  base: usize,
26
+ /// The stream offset alignment counts from (`XCDR.origin`); 0 except
27
+ /// inside an XCDR stream.
28
+ pub(crate) origin: usize,
26
29
  wstring_bom: bool,
27
30
  /// The valuetypes written so far (for indirections) and the chunk
28
31
  /// being written; made with the first value.
29
32
  pub(crate) values: Option<Box<crate::value::WriteState>>,
33
+ /// The 8-byte alignment points written since
34
+ /// [`track_align8`](Encoder::track_align8), each as the buffer length
35
+ /// before its padding and the padding written; `None` when not
36
+ /// tracked, or when something was written whose bytes depend on
37
+ /// stream offsets (see [`take_align8`](Encoder::take_align8)).
38
+ align8: Option<Vec<(usize, usize)>>,
30
39
  }
31
40
 
32
41
  macro_rules! write_number {
@@ -46,28 +55,30 @@ macro_rules! write_number {
46
55
 
47
56
  impl Encoder {
48
57
  /// Creates an encoder whose first byte is at stream offset 0.
49
- pub fn new(order: ByteOrder, version: CdrVersion) -> Encoder {
50
- Encoder::with_offset(order, version, 0)
58
+ pub fn new(order: ByteOrder, encoding: Encoding) -> Encoder {
59
+ Encoder::with_offset(order, encoding, 0)
51
60
  }
52
61
 
53
62
  /// Creates an encoder whose first byte is at stream offset `base`.
54
- pub fn with_offset(order: ByteOrder, version: CdrVersion, base: usize) -> Encoder {
63
+ pub fn with_offset(order: ByteOrder, encoding: Encoding, base: usize) -> Encoder {
55
64
  Encoder {
56
65
  buf: Vec::new(),
57
66
  shared: Vec::new(),
58
67
  shared_len: 0,
59
68
  allow_shared: false,
60
69
  order,
61
- version,
70
+ encoding,
62
71
  base,
72
+ origin: 0,
63
73
  wstring_bom: true,
64
74
  values: None,
75
+ align8: None,
65
76
  }
66
77
  }
67
78
 
68
79
  /// Starts an encapsulation: offset 0, with the byte order octet written.
69
- pub fn encapsulation(order: ByteOrder, version: CdrVersion) -> Encoder {
70
- let mut enc = Encoder::new(order, version);
80
+ pub fn encapsulation(order: ByteOrder, encoding: Encoding) -> Encoder {
81
+ let mut enc = Encoder::new(order, encoding);
71
82
  enc.write_octet(order.flag());
72
83
  enc
73
84
  }
@@ -86,16 +97,54 @@ impl Encoder {
86
97
  self.order
87
98
  }
88
99
 
89
- /// The GIOP version whose CDR rules apply.
90
- pub fn version(&self) -> CdrVersion {
91
- self.version
100
+ /// The encoding whose rules apply.
101
+ pub fn encoding(&self) -> Encoding {
102
+ self.encoding
92
103
  }
93
104
 
94
105
  /// The stream offset of the next byte.
106
+ ///
107
+ /// A caller that writes bytes depending on it (an offset or an
108
+ /// indirection) calls [`pin`](Encoder::pin) as well.
95
109
  pub fn position(&self) -> usize {
110
+ self.offset()
111
+ }
112
+
113
+ /// The stream offset of the next byte.
114
+ pub(crate) fn offset(&self) -> usize {
96
115
  self.base + self.len()
97
116
  }
98
117
 
118
+ /// Starts recording where the stream is aligned to 8 bytes, so that
119
+ /// the bytes written from here on can be moved by 4 bytes with
120
+ /// [`take_align8`](Encoder::take_align8). Only for GIOP encodings;
121
+ /// recording stops for good when something is written whose bytes
122
+ /// depend on stream offsets: a valuetype, a call to
123
+ /// [`pin`](Encoder::pin), [`set_origin`](Encoder::set_origin),
124
+ /// [`as_bytes_mut`](Encoder::as_bytes_mut) or
125
+ /// [`truncate`](Encoder::truncate).
126
+ pub fn track_align8(&mut self) {
127
+ self.align8 = self.encoding.is_giop().then(Vec::new);
128
+ }
129
+
130
+ /// Stops recording, and returns the 8-byte alignment points written
131
+ /// since [`track_align8`](Encoder::track_align8): each is the buffer
132
+ /// length before its padding and the length of that padding. Data
133
+ /// whose alignment is at most 4 does not depend on the stream offset
134
+ /// modulo 8, so the bytes written since can be moved by 4 bytes by
135
+ /// recomputing the padding at these points alone. `None` if not
136
+ /// recording, or if recording stopped.
137
+ pub fn take_align8(&mut self) -> Option<Vec<(usize, usize)>> {
138
+ self.align8.take()
139
+ }
140
+
141
+ /// Says that bytes written from here on depend on stream offsets, as
142
+ /// an indirection does, so the stream cannot be moved: stops
143
+ /// [`track_align8`](Encoder::track_align8) for good.
144
+ pub fn pin(&mut self) {
145
+ self.align8 = None;
146
+ }
147
+
99
148
  /// Bytes written so far, shared octets included.
100
149
  pub fn len(&self) -> usize {
101
150
  self.buf.len() + self.shared_len
@@ -116,12 +165,14 @@ impl Encoder {
116
165
  /// buffer indexes, which differ from stream offsets after shared
117
166
  /// octets.
118
167
  pub fn as_bytes_mut(&mut self) -> &mut [u8] {
168
+ self.align8 = None;
119
169
  &mut self.buf
120
170
  }
121
171
 
122
172
  /// Drops bytes past `len`, which must not be before shared octets.
123
173
  pub fn truncate(&mut self, len: usize) {
124
174
  debug_assert!(self.shared.last().is_none_or(|(at, _)| *at <= len));
175
+ self.align8 = None;
125
176
  self.buf.truncate(len);
126
177
  }
127
178
 
@@ -163,12 +214,40 @@ impl Encoder {
163
214
  self.allow_shared = allow;
164
215
  }
165
216
 
166
- /// Pads with zero octets until the stream offset is a multiple of `align`.
217
+ /// Pads with zero octets until the stream offset is a multiple of
218
+ /// `align`, or of the encoding's [`max_align`](Encoding::max_align)
219
+ /// when that is smaller.
220
+ ///
221
+ /// In an XCDR stream the offset counts from the alignment origin (see
222
+ /// [`set_origin`](Encoder::set_origin)).
167
223
  pub fn align(&mut self, align: usize) {
168
- let rem = self.position() % align;
169
- if rem != 0 {
170
- self.buf.resize(self.buf.len() + align - rem, 0);
224
+ let align = align.min(self.encoding.max_align());
225
+ let rem = (self.offset() - self.origin) % align;
226
+ let pad = if rem == 0 { 0 } else { align - rem };
227
+ if align == 8 {
228
+ if let Some(points) = self.align8.as_mut() {
229
+ points.push((self.buf.len(), pad));
230
+ }
171
231
  }
232
+ if pad != 0 {
233
+ self.buf.resize(self.buf.len() + pad, 0);
234
+ }
235
+ }
236
+
237
+ /// The stream offset alignment counts from: 0 unless changed with
238
+ /// [`set_origin`](Encoder::set_origin).
239
+ pub fn origin(&self) -> usize {
240
+ self.origin
241
+ }
242
+
243
+ /// Makes alignment count from stream offset `origin`, which must not
244
+ /// be past [`position`](Encoder::position). This is the XCDR
245
+ /// `PUSH(ORIGIN)`; the parameter headers of
246
+ /// [`begin_parameter`](Encoder::begin_parameter) do it themselves.
247
+ pub fn set_origin(&mut self, origin: usize) {
248
+ debug_assert!(origin <= self.offset());
249
+ self.align8 = None;
250
+ self.origin = origin;
172
251
  }
173
252
 
174
253
  /// Writes an `octet`.
@@ -236,10 +315,15 @@ impl Encoder {
236
315
 
237
316
  /// Writes a `sequence<octet>` without copying a large one, if the
238
317
  /// encoder [allows it](Encoder::allow_shared) and no valuetype is
239
- /// being written (whose chunk lengths count the buffer). Otherwise
318
+ /// being written (whose chunk lengths count the buffer), and the
319
+ /// encoding is a GIOP one (XCDR headers are patched in the buffer). Otherwise
240
320
  /// like [`write_octet_seq`](Encoder::write_octet_seq).
241
321
  pub fn write_octet_seq_shared(&mut self, octets: &Octets) -> Result<()> {
242
- if !self.allow_shared || octets.len() < SHARE_MIN || self.values.is_some() {
322
+ if !self.allow_shared
323
+ || octets.len() < SHARE_MIN
324
+ || self.values.is_some()
325
+ || !self.encoding.is_giop()
326
+ {
243
327
  return self.write_octet_seq(octets);
244
328
  }
245
329
  self.write_len(octets.len())?;
@@ -265,14 +349,14 @@ impl Encoder {
265
349
 
266
350
  /// Writes a `wchar` holding one UTF-16 code unit.
267
351
  ///
268
- /// GIOP 1.1 writes an aligned `unsigned short` in the stream byte order.
269
- /// GIOP 1.2 writes an octet length of 2 followed by the code unit in big
352
+ /// GIOP 1.1 and XCDR (`Char16`, DDS-XTypes 7.4.1.1.1) write an aligned
353
+ /// `unsigned short` in the stream byte order. GIOP 1.2 writes an octet length of 2 followed by the code unit in big
270
354
  /// endian without a BOM, as omniORB does.
271
355
  pub fn write_wchar(&mut self, value: u16) -> Result<()> {
272
- match self.version {
273
- CdrVersion::Giop1_0 => return Err(Error::WcharNotSupported),
274
- CdrVersion::Giop1_1 => self.write_u16(value),
275
- CdrVersion::Giop1_2 => {
356
+ match self.encoding {
357
+ Encoding::Giop1_0 => return Err(Error::WcharNotSupported),
358
+ Encoding::Giop1_1 | Encoding::Xcdr1 | Encoding::Xcdr2 => self.write_u16(value),
359
+ Encoding::Giop1_2 => {
276
360
  self.write_octet(2);
277
361
  self.write_octets(&value.to_be_bytes());
278
362
  }
@@ -287,11 +371,21 @@ impl Encoder {
287
371
  /// writes the octet length, then the code units without a terminator:
288
372
  /// by default a BOM followed by the stream byte order, or big endian
289
373
  /// without a BOM (see [`Encoder::set_wstring_bom`]). An empty string is
290
- /// just a zero length.
374
+ /// just a zero length. XCDR (DDS-XTypes 7.4.1.1.2) writes the length in
375
+ /// octets, then the code units in the stream byte order, without a BOM
376
+ /// or a terminator.
291
377
  pub fn write_wstring(&mut self, value: &str) -> Result<()> {
292
- match self.version {
293
- CdrVersion::Giop1_0 => Err(Error::WcharNotSupported),
294
- CdrVersion::Giop1_1 => {
378
+ match self.encoding {
379
+ Encoding::Giop1_0 => Err(Error::WcharNotSupported),
380
+ Encoding::Xcdr1 | Encoding::Xcdr2 => {
381
+ let units: Vec<u16> = value.encode_utf16().collect();
382
+ self.write_len(units.len().saturating_mul(2))?;
383
+ for unit in units {
384
+ self.write_u16(unit);
385
+ }
386
+ Ok(())
387
+ }
388
+ Encoding::Giop1_1 => {
295
389
  let units: Vec<u16> = value.encode_utf16().collect();
296
390
  self.write_len(units.len() + 1)?;
297
391
  for unit in units {
@@ -300,7 +394,7 @@ impl Encoder {
300
394
  self.write_u16(0);
301
395
  Ok(())
302
396
  }
303
- CdrVersion::Giop1_2 => {
397
+ Encoding::Giop1_2 => {
304
398
  let order = if self.wstring_bom {
305
399
  self.order
306
400
  } else {
@@ -329,7 +423,7 @@ impl Encoder {
329
423
  where
330
424
  F: FnOnce(&mut Encoder) -> Result<()>,
331
425
  {
332
- let mut inner = Encoder::encapsulation(self.order, self.version);
426
+ let mut inner = Encoder::encapsulation(self.order, self.encoding);
333
427
  inner.wstring_bom = self.wstring_bom;
334
428
  f(&mut inner)?;
335
429
  self.write_octet_seq(&inner.buf)
@@ -30,7 +30,7 @@ pub enum Error {
30
30
  InvalidWcharLength(u8),
31
31
  /// A GIOP 1.2 `wstring` had an odd octet length.
32
32
  OddWstringLength(u32),
33
- /// `wchar` and `wstring` cannot be used with GIOP 1.0.
33
+ /// `wchar` and `wstring` cannot be used with this encoding (GIOP 1.0).
34
34
  WcharNotSupported,
35
35
  /// A sequence or string length is larger than the bytes left.
36
36
  LengthTooLarge {
@@ -54,6 +54,11 @@ pub enum Error {
54
54
  /// indirection that points nowhere. On the writing side, an
55
55
  /// `end_value` without its `begin_value`.
56
56
  InvalidValue(&'static str),
57
+ /// An XCDR header was malformed: an unknown encapsulation identifier,
58
+ /// a DHEADER, EMHEADER or parameter length past the end of the data
59
+ /// that holds it, or a length too large for its header. On the
60
+ /// writing side, a member ID too large for its header.
61
+ InvalidXcdr(&'static str),
57
62
  }
58
63
 
59
64
  impl fmt::Display for Error {
@@ -70,7 +75,7 @@ impl fmt::Display for Error {
70
75
  Error::InvalidUtf16 => f.write_str("wide string is not valid UTF-16"),
71
76
  Error::InvalidWcharLength(n) => write!(f, "invalid wchar octet length {n}"),
72
77
  Error::OddWstringLength(n) => write!(f, "odd wstring octet length {n}"),
73
- Error::WcharNotSupported => f.write_str("wchar is not supported by GIOP 1.0"),
78
+ Error::WcharNotSupported => f.write_str("wchar is not supported by this encoding"),
74
79
  Error::LengthTooLarge { len, remaining } => write!(
75
80
  f,
76
81
  "length {len} is larger than the {remaining} bytes left in the stream"
@@ -82,6 +87,7 @@ impl fmt::Display for Error {
82
87
  Error::InvalidEnumValue(v) => write!(f, "invalid enum value {v}"),
83
88
  Error::InvalidTypeCode(why) => write!(f, "invalid TypeCode: {why}"),
84
89
  Error::InvalidValue(why) => write!(f, "invalid valuetype: {why}"),
90
+ Error::InvalidXcdr(why) => write!(f, "invalid XCDR: {why}"),
85
91
  }
86
92
  }
87
93
  }