vcdiff-decoder 0.1.0__tar.gz → 0.2.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.
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: vcdiff-decoder
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Python implementation of VCDIFF (RFC 3284) delta compression format
5
- Home-page: https://ably.com
6
5
  License: Apache-2.0
7
6
  Author: Ably
8
7
  Author-email: support@ably.com
@@ -20,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
22
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Project-URL: Homepage, https://ably.com
23
23
  Project-URL: Repository, https://github.com/ably/vcdiff-python
24
24
  Description-Content-Type: text/markdown
25
25
 
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "vcdiff-decoder"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "Python implementation of VCDIFF (RFC 3284) delta compression format"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -28,7 +28,7 @@ from .exceptions import (
28
28
  )
29
29
  from .types import InstructionType
30
30
 
31
- __version__ = "0.1.0"
31
+ __version__ = "0.2.0"
32
32
  __all__ = [
33
33
  "Decoder",
34
34
  "decode",
@@ -11,18 +11,19 @@ from .exceptions import VCDIFFError
11
11
  class AddressCache:
12
12
  """Manages address encoding/decoding for COPY instructions"""
13
13
 
14
- def __init__(self, near_size: int, same_size: int):
14
+ def __init__(self, near_size: int, same_blocks: int):
15
15
  """Initialize address cache with specified sizes
16
16
 
17
17
  Args:
18
- near_size: Size of the "near" address cache (typically 4)
19
- same_size: Size of the "same" address cache (typically 3 * 256)
18
+ near_size: s_near, the number of slots in the "near" cache (typically 4)
19
+ same_blocks: s_same, the number of 256-slot blocks in the "same" cache
20
+ (typically 3, so the cache holds 768 addresses)
20
21
  """
21
22
  self.near_size = near_size
22
- self.same_size = same_size
23
+ self.same_blocks = same_blocks
23
24
  self.near: List[int] = [0] * near_size
24
25
  self.next_near_slot = 0
25
- self.same: List[int] = [0] * (same_size * 256)
26
+ self.same: List[int] = [0] * (same_blocks * 256)
26
27
  self.address_stream: BinaryIO = io.BytesIO()
27
28
 
28
29
  def reset(self, addresses: bytes) -> None:
@@ -54,7 +55,7 @@ class AddressCache:
54
55
  The decoded address
55
56
 
56
57
  Raises:
57
- VCDIFFError: If the addressing mode is invalid or cache is uninitialized
58
+ VCDIFFError: If the addressing mode is invalid
58
59
  """
59
60
  # Validate addressing mode
60
61
  if mode > 8:
@@ -72,19 +73,18 @@ class AddressCache:
72
73
  else:
73
74
  # Near cache or same cache modes
74
75
  if mode - 2 < self.near_size:
75
- # Near cache
76
+ # Near cache. Both caches are zero filled at the start of a window
77
+ # (RFC 3284 section 5.1), so 0 is an ordinary cached address here.
76
78
  cache_index = mode - 2
77
- if self.near[cache_index] == 0:
78
- raise VCDIFFError(f"near cache slot {cache_index} is uninitialized")
79
79
  offset = read_varint(self.address_stream)
80
80
  addr = self.near[cache_index] + offset
81
81
  else:
82
82
  # Same cache
83
83
  m = mode - (2 + self.near_size)
84
- if m >= self.same_size:
84
+ if m >= self.same_blocks:
85
85
  raise VCDIFFError(
86
86
  f"same cache mode {mode} exceeds available slots "
87
- f"(max {2 + self.near_size + self.same_size - 1})"
87
+ f"(max {2 + self.near_size + self.same_blocks - 1})"
88
88
  )
89
89
 
90
90
  byte_data = self.address_stream.read(1)
@@ -107,5 +107,6 @@ class AddressCache:
107
107
  self.near[self.next_near_slot] = address
108
108
  self.next_near_slot = (self.next_near_slot + 1) % self.near_size
109
109
 
110
- if self.same_size > 0:
111
- self.same[address % (self.same_size * 256)] = address
110
+ if self.same_blocks > 0:
111
+ # RFC 3284 section 5.1: the slot with index addr % (s_same * 256)
112
+ self.same[address % len(self.same)] = address
@@ -8,7 +8,7 @@ from .types import (
8
8
  VCDIFF_MAGIC, VCDIFF_VERSION, MINIMUM_FILE_SIZE,
9
9
  VCD_DECOMPRESS, VCD_CODETABLE, VCD_APPHEADER,
10
10
  VCD_SOURCE, VCD_TARGET, VCD_ADLER32,
11
- NEAR_CACHE_SIZE, SAME_CACHE_SIZE
11
+ NEAR_CACHE_SIZE, SAME_CACHE_BLOCKS
12
12
  )
13
13
  from .exceptions import (
14
14
  VCDIFFError, InvalidMagicError, InvalidVersionError, InvalidFormatError,
@@ -71,7 +71,7 @@ class Decoder:
71
71
  VCDIFFError: If the window cannot be decoded
72
72
  """
73
73
  # Initialize address cache
74
- address_cache = AddressCache(NEAR_CACHE_SIZE, SAME_CACHE_SIZE)
74
+ address_cache = AddressCache(NEAR_CACHE_SIZE, SAME_CACHE_BLOCKS)
75
75
  address_cache.reset(window.address_section)
76
76
 
77
77
  # Create target buffer
@@ -281,7 +281,7 @@ def parse_delta(delta: Union[bytes, bytearray]) -> ParsedDelta:
281
281
  parsed.windows.append(window)
282
282
 
283
283
  # Create address cache for this window
284
- address_cache = AddressCache(NEAR_CACHE_SIZE, SAME_CACHE_SIZE)
284
+ address_cache = AddressCache(NEAR_CACHE_SIZE, SAME_CACHE_BLOCKS)
285
285
  address_cache.reset(window.address_section)
286
286
 
287
287
  # Parse instructions using the instruction section and data section
@@ -38,9 +38,9 @@ ADD_INSTRUCTION_MAX = 161 # ADD instructions: 18-161
38
38
  COPY_INSTRUCTION_MIN = 162 # COPY instructions: 162-255
39
39
  COPY_INSTRUCTION_MAX = 255 # COPY instructions: 162-255
40
40
 
41
- # Address cache configuration - RFC 3284 Section 5.3
42
- NEAR_CACHE_SIZE = 4 # Size of "near" address cache
43
- SAME_CACHE_SIZE = 3 * 256 # Size of "same" address cache
41
+ # Address cache configuration - RFC 3284 Section 5.1
42
+ NEAR_CACHE_SIZE = 4 # s_near: number of slots in the "near" address cache
43
+ SAME_CACHE_BLOCKS = 3 # s_same: the "same" address cache holds s_same * 256 slots
44
44
  INSTRUCTION_TABLE_SIZE = 256 # Size of instruction code table
45
45
 
46
46
  # File format validation constants
File without changes
File without changes