OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/hpack_encoder.h" | 5 #include "net/spdy/hpack_encoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/spdy/hpack_header_table.h" | 10 #include "net/spdy/hpack_header_table.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 evictee->set_state(kNoState); | 73 evictee->set_state(kNoState); |
74 } | 74 } |
75 } | 75 } |
76 if (entry != NULL) { | 76 if (entry != NULL) { |
77 EmitStaticIndex(entry); | 77 EmitStaticIndex(entry); |
78 } else { | 78 } else { |
79 EmitIndexedLiteral(*it); | 79 EmitIndexedLiteral(*it); |
80 } | 80 } |
81 } | 81 } |
82 // Walk the reference set, toggling off as needed and clearing encoding state. | 82 // Walk the reference set, toggling off as needed and clearing encoding state. |
83 for (HpackEntry::OrderedSet::const_iterator it = | 83 for (HpackHeaderTable::OrderedEntrySet::const_iterator it = |
84 header_table_.reference_set().begin(); | 84 header_table_.reference_set().begin(); |
85 it != header_table_.reference_set().end();) { | 85 it != header_table_.reference_set().end();) { |
86 HpackEntry* entry = *(it++); // Step to prevent invalidation. | 86 HpackEntry* entry = *(it++); // Step to prevent invalidation. |
87 CHECK_NE(kNoState, entry->state()); | 87 CHECK_NE(kNoState, entry->state()); |
88 | 88 |
89 if (entry->state() == kReferencedExplicitOff) { | 89 if (entry->state() == kReferencedExplicitOff) { |
90 // Explicitly toggle off. | 90 // Explicitly toggle off. |
91 EmitDynamicIndex(entry); | 91 EmitDynamicIndex(entry); |
92 } | 92 } |
93 entry->set_state(kNoState); | 93 entry->set_state(kNoState); |
94 } | 94 } |
(...skipping 12 matching lines...) Expand all Loading... |
107 EmitNonIndexedLiteral(*it); | 107 EmitNonIndexedLiteral(*it); |
108 } | 108 } |
109 allow_huffman_compression_ = true; | 109 allow_huffman_compression_ = true; |
110 output_stream_.TakeString(output); | 110 output_stream_.TakeString(output); |
111 return true; | 111 return true; |
112 } | 112 } |
113 | 113 |
114 void HpackEncoder::EmitDynamicIndex(HpackEntry* entry) { | 114 void HpackEncoder::EmitDynamicIndex(HpackEntry* entry) { |
115 DCHECK(!entry->IsStatic()); | 115 DCHECK(!entry->IsStatic()); |
116 output_stream_.AppendPrefix(kIndexedOpcode); | 116 output_stream_.AppendPrefix(kIndexedOpcode); |
117 output_stream_.AppendUint32(entry->Index()); | 117 output_stream_.AppendUint32(header_table_.IndexOf(entry)); |
118 | 118 |
119 entry->set_state(kNoState); | 119 entry->set_state(kNoState); |
120 if (header_table_.Toggle(entry)) { | 120 if (header_table_.Toggle(entry)) { |
121 // Was added to the reference set. | 121 // Was added to the reference set. |
122 entry->set_state(kReferencedThisEncoding); | 122 entry->set_state(kReferencedThisEncoding); |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 void HpackEncoder::EmitStaticIndex(HpackEntry* entry) { | 126 void HpackEncoder::EmitStaticIndex(HpackEntry* entry) { |
127 DCHECK(entry->IsStatic()); | 127 DCHECK(entry->IsStatic()); |
128 output_stream_.AppendPrefix(kIndexedOpcode); | 128 output_stream_.AppendPrefix(kIndexedOpcode); |
129 output_stream_.AppendUint32(entry->Index()); | 129 output_stream_.AppendUint32(header_table_.IndexOf(entry)); |
130 | 130 |
131 HpackEntry* new_entry = header_table_.TryAddEntry(entry->name(), | 131 HpackEntry* new_entry = header_table_.TryAddEntry(entry->name(), |
132 entry->value()); | 132 entry->value()); |
133 if (new_entry) { | 133 if (new_entry) { |
134 // This is a static entry: no need to pin. | 134 // This is a static entry: no need to pin. |
135 header_table_.Toggle(new_entry); | 135 header_table_.Toggle(new_entry); |
136 new_entry->set_state(kReferencedThisEncoding); | 136 new_entry->set_state(kReferencedThisEncoding); |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
(...skipping 13 matching lines...) Expand all Loading... |
153 const Representation& representation) { | 153 const Representation& representation) { |
154 output_stream_.AppendPrefix(kLiteralNoIndexOpcode); | 154 output_stream_.AppendPrefix(kLiteralNoIndexOpcode); |
155 output_stream_.AppendUint32(0); | 155 output_stream_.AppendUint32(0); |
156 EmitString(representation.first); | 156 EmitString(representation.first); |
157 EmitString(representation.second); | 157 EmitString(representation.second); |
158 } | 158 } |
159 | 159 |
160 void HpackEncoder::EmitLiteral(const Representation& representation) { | 160 void HpackEncoder::EmitLiteral(const Representation& representation) { |
161 const HpackEntry* name_entry = header_table_.GetByName(representation.first); | 161 const HpackEntry* name_entry = header_table_.GetByName(representation.first); |
162 if (name_entry != NULL) { | 162 if (name_entry != NULL) { |
163 output_stream_.AppendUint32(name_entry->Index()); | 163 output_stream_.AppendUint32(header_table_.IndexOf(name_entry)); |
164 } else { | 164 } else { |
165 output_stream_.AppendUint32(0); | 165 output_stream_.AppendUint32(0); |
166 EmitString(representation.first); | 166 EmitString(representation.first); |
167 } | 167 } |
168 EmitString(representation.second); | 168 EmitString(representation.second); |
169 } | 169 } |
170 | 170 |
171 void HpackEncoder::EmitString(StringPiece str) { | 171 void HpackEncoder::EmitString(StringPiece str) { |
172 size_t encoded_size = (!allow_huffman_compression_ ? str.size() | 172 size_t encoded_size = (!allow_huffman_compression_ ? str.size() |
173 : huffman_table_.EncodedSize(str)); | 173 : huffman_table_.EncodedSize(str)); |
(...skipping 22 matching lines...) Expand all Loading... |
196 } else { | 196 } else { |
197 // Note std::map guarantees representations are ordered. | 197 // Note std::map guarantees representations are ordered. |
198 full_set.push_back(make_pair( | 198 full_set.push_back(make_pair( |
199 StringPiece(it->first), StringPiece(it->second))); | 199 StringPiece(it->first), StringPiece(it->second))); |
200 } | 200 } |
201 } | 201 } |
202 // Perform a linear merge of ordered representations with the (also ordered) | 202 // Perform a linear merge of ordered representations with the (also ordered) |
203 // reference set. Mark each referenced entry with current membership state, | 203 // reference set. Mark each referenced entry with current membership state, |
204 // and gather representations which must be explicitly emitted. | 204 // and gather representations which must be explicitly emitted. |
205 Representations::const_iterator r_it = full_set.begin(); | 205 Representations::const_iterator r_it = full_set.begin(); |
206 HpackEntry::OrderedSet::const_iterator s_it = | 206 HpackHeaderTable::OrderedEntrySet::const_iterator s_it = |
207 header_table_.reference_set().begin(); | 207 header_table_.reference_set().begin(); |
208 | 208 |
209 Representations explicit_set; | 209 Representations explicit_set; |
210 while (r_it != full_set.end() && | 210 while (r_it != full_set.end() && |
211 s_it != header_table_.reference_set().end()) { | 211 s_it != header_table_.reference_set().end()) { |
212 // Compare on name, then value. | 212 // Compare on name, then value. |
213 int result = r_it->first.compare((*s_it)->name()); | 213 int result = r_it->first.compare((*s_it)->name()); |
214 if (result == 0) { | 214 if (result == 0) { |
215 result = r_it->second.compare((*s_it)->value()); | 215 result = r_it->second.compare((*s_it)->value()); |
216 } | 216 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 pos++; | 282 pos++; |
283 } | 283 } |
284 } | 284 } |
285 // Sort crumbs and remove duplicates. | 285 // Sort crumbs and remove duplicates. |
286 std::sort(out->begin() + prior_size, out->end()); | 286 std::sort(out->begin() + prior_size, out->end()); |
287 out->erase(std::unique(out->begin() + prior_size, out->end()), | 287 out->erase(std::unique(out->begin() + prior_size, out->end()), |
288 out->end()); | 288 out->end()); |
289 } | 289 } |
290 | 290 |
291 } // namespace net | 291 } // namespace net |
OLD | NEW |