private void _merge_prefix(LinkedList<byte[]> deque, int size) { /*Replace the first entries in a deque of strings with a single string of up to size bytes. >>> d = collections.deque(['abc', 'de', 'fghi', 'j']) >>> _merge_prefix(d, 5); print d deque(['abcde', 'fghi', 'j']) Strings will be split as necessary to reach the desired size. >>> _merge_prefix(d, 7); print d deque(['abcdefg', 'hi', 'j']) >>> _merge_prefix(d, 3); print d deque(['abc', 'defg', 'hi', 'j']) >>> _merge_prefix(d, 100); print d deque(['abcdefghij']) */ if (deque.Count == 1 && deque.at(0).Length <= size) return; var prefix = new List<byte[]>(); var remaining = size; while (deque.Any() && remaining > 0) { var chunk = deque.popleft(); if (chunk.Length > remaining) { var segment = new ArraySegment<byte>(chunk, remaining, chunk.Length - remaining); deque.AddFirst(chunk.substr(remaining)); // deque.AddFirst(chunk[remaining:]); chunk = chunk.substr(0, remaining); // chunk = chunk[:remaining]; } prefix.Add(chunk); remaining -= chunk.Length; } // This data structure normally just contains byte strings, but // the unittest gets messy if it doesn't use the default str() type, // so do the merge based on the type of data that's actually present. if (prefix.Count > 0) deque.AddFirst(ByteArrayExtensions.join(prefix.ToArray())); if (deque.Count == 0) deque.AddFirst(new byte[] {}); }
private void _double_prefix(LinkedList<byte[]> deque) { /* Grow by doubling, but don't split the second chunk just because the first one is small. */ var new_len = Math.Max(deque.at(0).Length * 2, deque.at(0).Length + deque.at(1).Length); _merge_prefix(deque, new_len); }