| 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 |