Refactor EncodeRequiredInsertCount() and DecodeRequiredInsertCount().

DecodeRequiredInsertCount() is used in QpackProgressiveDecoder.
EncodeRequiredInsertCount() is used for testing DecodeRequiredInsertCount(), and
soon will be used in QpackEncoder.  Clearely they belong to their own build
target to avoid heavyweight dependencies between encoder and decoder.

gfe-relnote: n/a, QUIC v99-only change.
PiperOrigin-RevId: 257903034
Change-Id: I956a3416018cc5e35dbb4b41861115a1ccb8f018
diff --git a/quic/core/qpack/qpack_progressive_decoder.cc b/quic/core/qpack/qpack_progressive_decoder.cc
index 07e2091..e364edc 100644
--- a/quic/core/qpack/qpack_progressive_decoder.cc
+++ b/quic/core/qpack/qpack_progressive_decoder.cc
@@ -8,6 +8,7 @@
 #include <limits>
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
 
@@ -33,56 +34,6 @@
       decoding_(true),
       error_detected_(false) {}
 
-// static
-bool QpackProgressiveDecoder::DecodeRequiredInsertCount(
-    uint64_t encoded_required_insert_count,
-    uint64_t max_entries,
-    uint64_t total_number_of_inserts,
-    uint64_t* required_insert_count) {
-  if (encoded_required_insert_count == 0) {
-    *required_insert_count = 0;
-    return true;
-  }
-
-  // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
-  // precluding all calculations in this method from overflowing.
-  DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
-
-  if (encoded_required_insert_count > 2 * max_entries) {
-    return false;
-  }
-
-  *required_insert_count = encoded_required_insert_count - 1;
-  DCHECK_LT(*required_insert_count, std::numeric_limits<uint64_t>::max() / 16);
-
-  uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
-  DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
-
-  if (current_wrapped >= *required_insert_count + max_entries) {
-    // Required Insert Count wrapped around 1 extra time.
-    *required_insert_count += 2 * max_entries;
-  } else if (current_wrapped + max_entries < *required_insert_count) {
-    // Decoder wrapped around 1 extra time.
-    current_wrapped += 2 * max_entries;
-  }
-
-  if (*required_insert_count >
-      std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
-    return false;
-  }
-
-  *required_insert_count += total_number_of_inserts;
-
-  // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
-  if (current_wrapped >= *required_insert_count) {
-    return false;
-  }
-
-  *required_insert_count -= current_wrapped;
-
-  return true;
-}
-
 void QpackProgressiveDecoder::Decode(QuicStringPiece data) {
   DCHECK(decoding_);
 
@@ -317,7 +268,7 @@
 bool QpackProgressiveDecoder::DoPrefixInstruction() {
   DCHECK(!prefix_decoded_);
 
-  if (!DecodeRequiredInsertCount(
+  if (!QpackDecodeRequiredInsertCount(
           prefix_decoder_->varint(), header_table_->max_entries(),
           header_table_->inserted_entry_count(), &required_insert_count_)) {
     OnError("Error decoding Required Insert Count.");
diff --git a/quic/core/qpack/qpack_progressive_decoder.h b/quic/core/qpack/qpack_progressive_decoder.h
index c2e8f87..3abf427 100644
--- a/quic/core/qpack/qpack_progressive_decoder.h
+++ b/quic/core/qpack/qpack_progressive_decoder.h
@@ -58,15 +58,6 @@
   QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
   ~QpackProgressiveDecoder() override = default;
 
-  // Calculate Required Insert Count from Encoded Required Insert Count,
-  // MaxEntries, and total number of dynamic table insertions according to
-  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
-  // Returns true on success, false on invalid input or overflow/underflow.
-  static bool DecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
-                                        uint64_t max_entries,
-                                        uint64_t total_number_of_inserts,
-                                        uint64_t* required_insert_count);
-
   // Provide a data fragment to decode.
   void Decode(QuicStringPiece data);
 
diff --git a/quic/core/qpack/qpack_required_insert_count.cc b/quic/core/qpack/qpack_required_insert_count.cc
new file mode 100644
index 0000000..22541e6
--- /dev/null
+++ b/quic/core/qpack/qpack_required_insert_count.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h"
+
+#include <limits>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
+
+namespace quic {
+
+uint64_t QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                                        uint64_t max_entries) {
+  if (required_insert_count == 0) {
+    return 0;
+  }
+
+  return required_insert_count % (2 * max_entries) + 1;
+}
+
+bool QpackDecodeRequiredInsertCount(uint64_t encoded_required_insert_count,
+                                    uint64_t max_entries,
+                                    uint64_t total_number_of_inserts,
+                                    uint64_t* required_insert_count) {
+  if (encoded_required_insert_count == 0) {
+    *required_insert_count = 0;
+    return true;
+  }
+
+  // |max_entries| is calculated by dividing an unsigned 64-bit integer by 32,
+  // precluding all calculations in this method from overflowing.
+  DCHECK_LE(max_entries, std::numeric_limits<uint64_t>::max() / 32);
+
+  if (encoded_required_insert_count > 2 * max_entries) {
+    return false;
+  }
+
+  *required_insert_count = encoded_required_insert_count - 1;
+  DCHECK_LT(*required_insert_count, std::numeric_limits<uint64_t>::max() / 16);
+
+  uint64_t current_wrapped = total_number_of_inserts % (2 * max_entries);
+  DCHECK_LT(current_wrapped, std::numeric_limits<uint64_t>::max() / 16);
+
+  if (current_wrapped >= *required_insert_count + max_entries) {
+    // Required Insert Count wrapped around 1 extra time.
+    *required_insert_count += 2 * max_entries;
+  } else if (current_wrapped + max_entries < *required_insert_count) {
+    // Decoder wrapped around 1 extra time.
+    current_wrapped += 2 * max_entries;
+  }
+
+  if (*required_insert_count >
+      std::numeric_limits<uint64_t>::max() - total_number_of_inserts) {
+    return false;
+  }
+
+  *required_insert_count += total_number_of_inserts;
+
+  // Prevent underflow, also disallow invalid value 0 for Required Insert Count.
+  if (current_wrapped >= *required_insert_count) {
+    return false;
+  }
+
+  *required_insert_count -= current_wrapped;
+
+  return true;
+}
+
+}  // namespace quic
diff --git a/quic/core/qpack/qpack_required_insert_count.h b/quic/core/qpack/qpack_required_insert_count.h
new file mode 100644
index 0000000..7f489bc
--- /dev/null
+++ b/quic/core/qpack/qpack_required_insert_count.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
+#define QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
+
+#include <cstdint>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Calculate Encoded Required Insert Count from Required Insert Count and
+// MaxEntries according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.
+QUIC_EXPORT_PRIVATE uint64_t
+QpackEncodeRequiredInsertCount(uint64_t required_insert_count,
+                               uint64_t max_entries);
+
+// Calculate Required Insert Count from Encoded Required Insert Count,
+// MaxEntries, and total number of dynamic table insertions according to
+// https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#ric.  Returns true
+// on success, false on invalid input or overflow/underflow.
+QUIC_EXPORT_PRIVATE bool QpackDecodeRequiredInsertCount(
+    uint64_t encoded_required_insert_count,
+    uint64_t max_entries,
+    uint64_t total_number_of_inserts,
+    uint64_t* required_insert_count);
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_REQUIRED_INSERT_COUNT_H_
diff --git a/quic/core/qpack/qpack_progressive_decoder_test.cc b/quic/core/qpack/qpack_required_insert_count_test.cc
similarity index 81%
rename from quic/core/qpack/qpack_progressive_decoder_test.cc
rename to quic/core/qpack/qpack_required_insert_count_test.cc
index b306702..a84548d 100644
--- a/quic/core/qpack/qpack_progressive_decoder_test.cc
+++ b/quic/core/qpack/qpack_required_insert_count_test.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h"
+#include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h"
 
 #include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
@@ -11,6 +11,16 @@
 namespace test {
 namespace {
 
+TEST(QpackRequiredInsertCountTest, QpackEncodeRequiredInsertCount) {
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 0));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 8));
+  EXPECT_EQ(0u, QpackEncodeRequiredInsertCount(0, 1024));
+
+  EXPECT_EQ(2u, QpackEncodeRequiredInsertCount(1, 8));
+  EXPECT_EQ(5u, QpackEncodeRequiredInsertCount(20, 8));
+  EXPECT_EQ(7u, QpackEncodeRequiredInsertCount(106, 10));
+}
+
 // For testing valid decodings, the Encoded Required Insert Count is calculated
 // from Required Insert Count, so that there is an expected value to compare
 // the decoded value against, and so that intricate inequalities can be
@@ -39,16 +49,7 @@
     {401, 100, 500},
     {600, 100, 500}};
 
-uint64_t EncodeRequiredInsertCount(uint64_t required_insert_count,
-                                   uint64_t max_entries) {
-  if (required_insert_count == 0) {
-    return 0;
-  }
-
-  return required_insert_count % (2 * max_entries) + 1;
-}
-
-TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCount) {
+TEST(QpackRequiredInsertCountTest, QpackDecodeRequiredInsertCount) {
   for (size_t i = 0; i < QUIC_ARRAYSIZE(kTestData); ++i) {
     const uint64_t required_insert_count = kTestData[i].required_insert_count;
     const uint64_t max_entries = kTestData[i].max_entries;
@@ -71,13 +72,13 @@
     }
 
     uint64_t encoded_required_insert_count =
-        EncodeRequiredInsertCount(required_insert_count, max_entries);
+        QpackEncodeRequiredInsertCount(required_insert_count, max_entries);
 
     // Initialize to a value different from the expected output to confirm that
-    // DecodeRequiredInsertCount() modifies the value of
+    // QpackDecodeRequiredInsertCount() modifies the value of
     // |decoded_required_insert_count|.
     uint64_t decoded_required_insert_count = required_insert_count + 1;
-    EXPECT_TRUE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
+    EXPECT_TRUE(QpackDecodeRequiredInsertCount(
         encoded_required_insert_count, max_entries, total_number_of_inserts,
         &decoded_required_insert_count))
         << i;
@@ -107,10 +108,10 @@
     {400, 100, 500},
     {601, 100, 500}};
 
-TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCountError) {
+TEST(QpackRequiredInsertCountTest, DecodeRequiredInsertCountError) {
   for (size_t i = 0; i < QUIC_ARRAYSIZE(kInvalidTestData); ++i) {
     uint64_t decoded_required_insert_count = 0;
-    EXPECT_FALSE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
+    EXPECT_FALSE(QpackDecodeRequiredInsertCount(
         kInvalidTestData[i].encoded_required_insert_count,
         kInvalidTestData[i].max_entries,
         kInvalidTestData[i].total_number_of_inserts,