public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var obj = JObject.Load(reader); var ps = obj.Properties().ToArray(); var result = new HpackHeaderField((AsciiString)ps[0].Name, (AsciiString)(ps[0].Value.ToString())); return(result); }
public void TestLength() { HpackDynamicTable table = new HpackDynamicTable(100); Assert.Equal(0, table.Length()); HpackHeaderField entry = new HpackHeaderField((AsciiString)"foo", (AsciiString)"bar"); table.Add(entry); Assert.Equal(1, table.Length()); table.Clear(); Assert.Equal(0, table.Length()); }
public void TestRemove() { HpackDynamicTable table = new HpackDynamicTable(100); Assert.Null(table.Remove()); HpackHeaderField entry1 = new HpackHeaderField((AsciiString)"foo", (AsciiString)"bar"); HpackHeaderField entry2 = new HpackHeaderField((AsciiString)"hello", (AsciiString)"world"); table.Add(entry1); table.Add(entry2); Assert.Equal(entry1, table.Remove()); Assert.Equal(entry2, table.GetEntry(1)); Assert.Equal(1, table.Length()); Assert.Equal(entry2.Size(), table.Size()); }
/// <summary> /// Remove and return the oldest header field from the dynamic table. /// </summary> public HpackHeaderField Remove() { HpackHeaderField removed = _hpackHeaderFields[_tail]; if (removed is null) { return(null); } _size -= removed.Size(); _hpackHeaderFields[_tail++] = null; if (_tail == _hpackHeaderFields.Length) { _tail = 0; } return(removed); }
public void TestGetEntry() { HpackDynamicTable table = new HpackDynamicTable(100); HpackHeaderField entry = new HpackHeaderField((AsciiString)"foo", (AsciiString)"bar"); table.Add(entry); Assert.Equal(entry, table.GetEntry(1)); table.Clear(); try { table.GetEntry(1); Assert.False(true); } catch (IndexOutOfRangeException) { //success } }
/// <summary> /// Add the header field to the dynamic table. Entries are evicted from the dynamic table until /// the size of the table and the new header field is less than or equal to the table's capacity. /// If the size of the new entry is larger than the table's capacity, the dynamic table will be /// cleared. /// </summary> /// <param name="header"></param> public void Add(HpackHeaderField header) { int headerSize = header.Size(); if (headerSize > _capacity) { Clear(); return; } while (_capacity - _size < headerSize) { _ = Remove(); } _hpackHeaderFields[_head++] = header; _size += header.Size(); if (_head == _hpackHeaderFields.Length) { _head = 0; } }
public void TestSetCapacity() { HpackHeaderField entry1 = new HpackHeaderField((AsciiString)"foo", (AsciiString)"bar"); HpackHeaderField entry2 = new HpackHeaderField((AsciiString)"hello", (AsciiString)"world"); int size1 = entry1.Size(); int size2 = entry2.Size(); HpackDynamicTable table = new HpackDynamicTable(size1 + size2); table.Add(entry1); table.Add(entry2); Assert.Equal(2, table.Length()); Assert.Equal(size1 + size2, table.Size()); table.SetCapacity((size1 + size2) * 2); //larger capacity Assert.Equal(2, table.Length()); Assert.Equal(size1 + size2, table.Size()); table.SetCapacity(size2); //smaller capacity //entry1 will be removed Assert.Equal(1, table.Length()); Assert.Equal(size2, table.Size()); Assert.Equal(entry2, table.GetEntry(1)); table.SetCapacity(0); //clear all Assert.Equal(0, table.Length()); Assert.Equal(0, table.Size()); }
/// <summary> /// Set the maximum size of the dynamic table. Entries are evicted from the dynamic table until /// the size of the table is less than or equal to the maximum size. /// </summary> /// <param name="capacity"></param> public void SetCapacity(long capacity) { if (capacity < Http2CodecUtil.MinHeaderTableSize || capacity > Http2CodecUtil.MaxHeaderTableSize) { ThrowHelper.ThrowArgumentException_InvalidCapacity(capacity); } // initially capacity will be -1 so init won't return here if (_capacity == capacity) { return; } _capacity = capacity; if (0ul >= (ulong)capacity) { Clear(); } else { // initially _size will be 0 so remove won't be called while (_size > capacity) { _ = Remove(); } } int maxEntries = (int)(capacity / HpackHeaderField.HeaderEntryOverhead); if (capacity % HpackHeaderField.HeaderEntryOverhead != 0) { maxEntries++; } // check if capacity change requires us to reallocate the array if (_hpackHeaderFields is object && _hpackHeaderFields.Length == maxEntries) { return; } HpackHeaderField[] tmp = new HpackHeaderField[maxEntries]; // initially length will be 0 so there will be no copy int len = Length(); int cursor = _tail; for (int i = 0; i < len; i++) { HpackHeaderField entry = _hpackHeaderFields[cursor++]; tmp[i] = entry; if (cursor == _hpackHeaderFields.Length) { cursor = 0; } } _tail = 0; _head = _tail + len; _hpackHeaderFields = tmp; }