Index: components/payments/content/payment_manifest_section_table.cc |
diff --git a/components/payments/content/payment_manifest_section_table.cc b/components/payments/content/payment_manifest_section_table.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1a966ae4d547e3207f56461f4dbd7361464cdd49 |
--- /dev/null |
+++ b/components/payments/content/payment_manifest_section_table.cc |
@@ -0,0 +1,184 @@ |
+// Copyright 2017 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 "components/payments/content/payment_manifest_section_table.h" |
+ |
+#include <stdint.h> |
+ |
+#include <memory> |
+ |
+#include "base/logging.h" |
+#include "sql/statement.h" |
+ |
+namespace payments { |
+namespace { |
+ |
+// Note that the finger print is calculated with SHA-256. |
+const size_t kFingerPrintLength = 32; |
+ |
+WebDatabaseTable::TypeKey GetKey() { |
+ // We just need a unique constant. Use the address of a static that |
+ // COMDAT folding won't touch in an optimizing linker. |
+ static int table_key = 0; |
+ return reinterpret_cast<void*>(&table_key); |
+} |
+ |
+// Converts 2-dimensional vector |finger_prints| to 1-dimesional vector. |
+std::unique_ptr<std::vector<uint8_t>> SerializeFingerPrints( |
+ const std::vector<std::vector<uint8_t>>& finger_prints) { |
+ auto serialized_finger_prints = base::MakeUnique<std::vector<uint8_t>>(); |
+ |
+ for (const auto finger_print : finger_prints) { |
please use gerrit instead
2017/04/06 14:35:29
Let's put a "&" after "auto" to make sure that no
gogerald1
2017/04/06 16:42:09
Done.
|
+ DCHECK(finger_print.size() == kFingerPrintLength); |
please use gerrit instead
2017/04/06 14:35:28
DCHECK_EQ(kFingerPrintLength, finger_print.size())
gogerald1
2017/04/06 16:42:09
Done.
|
+ serialized_finger_prints->insert(serialized_finger_prints->end(), |
+ finger_print.begin(), finger_print.end()); |
+ } |
+ |
+ return serialized_finger_prints; |
+} |
+ |
+// Converts 1-dimensional vector created by SerializeFingerPrints back to |
+// 2-dimensional vector. Each vector of the second dimensional vector has exact |
+// kFingerPrintLength number of elements. |
+bool DeserializeFingerPrints( |
+ const std::vector<uint8_t>& finger_prints, |
+ std::vector<std::vector<uint8_t>>& deserialized_finger_prints) { |
please use gerrit instead
2017/04/06 14:35:29
Output is usually a pointer instead of ref.
gogerald1
2017/04/06 16:42:09
Agreed, but ref looks slightly better here since d
|
+ if (finger_prints.size() % kFingerPrintLength != 0) |
+ return false; |
+ |
+ for (size_t i = 0; i < finger_prints.size();) { |
please use gerrit instead
2017/04/06 14:35:29
You can move i+=kFingerprintlength into this line.
gogerald1
2017/04/06 16:42:09
Done.
|
+ deserialized_finger_prints.emplace_back( |
+ finger_prints.begin() + i, |
+ finger_prints.begin() + i + kFingerPrintLength); |
+ i += kFingerPrintLength; |
+ } |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+PaymentManifestSectionTable::PaymentManifestSectionTable() {} |
+ |
+PaymentManifestSectionTable::~PaymentManifestSectionTable() {} |
+ |
+PaymentManifestSectionTable* PaymentManifestSectionTable::FromWebDatabase( |
+ WebDatabase* db) { |
+ return static_cast<PaymentManifestSectionTable*>(db->GetTable(GetKey())); |
+} |
+ |
+WebDatabaseTable::TypeKey PaymentManifestSectionTable::GetTypeKey() const { |
+ return GetKey(); |
+} |
+ |
+bool PaymentManifestSectionTable::CreateTablesIfNecessary() { |
+ if (!db_->DoesTableExist("payment_manifest_section")) { |
+ if (!db_->Execute("CREATE TABLE payment_manifest_section ( " |
+ "method_name VARCHAR, " |
+ "package_name VARCHAR, " |
+ "version INTEGER NOT NULL DEFAULT 0, " |
+ "finger_prints BLOB) ")) { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |
+ |
+bool PaymentManifestSectionTable::IsSyncable() { |
+ return false; |
+} |
+ |
+bool PaymentManifestSectionTable::MigrateToVersion( |
+ int version, |
+ bool* update_compatible_version) { |
+ return true; |
+} |
+ |
+bool PaymentManifestSectionTable::AddPaymentManifestSections( |
+ const std::string& method_name, |
+ const std::vector<mojom::PaymentManifestSectionPtr>& manifest) { |
+ if (!db_->BeginTransaction()) |
+ return false; |
+ |
+ sql::Statement s1(db_->GetUniqueStatement( |
+ "DELETE FROM payment_manifest_section WHERE method_name=?")); |
+ s1.BindString(0, method_name); |
+ |
+ if (!s1.Run()) { |
+ db_->RollbackTransaction(); |
+ return false; |
+ } |
+ |
+ sql::Statement s2(db_->GetUniqueStatement( |
+ "INSERT INTO payment_manifest_section " |
+ "(method_name, package_name, version, finger_prints) " |
+ "VALUES (?, ?, ?, ?)")); |
+ for (size_t i = 0; i < manifest.size(); i++) { |
+ int index = 0; |
+ s2.BindString(index++, method_name); |
+ s2.BindString(index++, manifest[i]->package_name); |
+ s2.BindInt64(index++, manifest[i]->version); |
+ |
+ std::unique_ptr<std::vector<uint8_t>> serialized_finger_prints = |
+ SerializeFingerPrints(manifest[i]->sha256_cert_fingerprints); |
+ s2.BindBlob(index, serialized_finger_prints->data(), |
+ serialized_finger_prints->size()); |
+ |
+ if (!s2.Run()) { |
+ db_->RollbackTransaction(); |
+ return false; |
+ } |
+ s2.Reset(true); |
+ } |
+ |
+ if (!db_->CommitTransaction()) { |
+ db_->RollbackTransaction(); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+std::vector<mojom::PaymentManifestSectionPtr> |
+PaymentManifestSectionTable::GetPaymentManifestSections( |
+ const std::string& method_name) { |
+ std::vector<mojom::PaymentManifestSectionPtr> manifest; |
+ sql::Statement s( |
+ db_->GetUniqueStatement("SELECT package_name, version, finger_prints " |
+ "FROM payment_manifest_section " |
+ "WHERE method_name=?")); |
+ s.BindString(0, method_name); |
+ |
+ if (!s.is_valid()) { |
+ return manifest; |
+ } |
+ |
+ while (s.Step()) { |
+ mojom::PaymentManifestSectionPtr section = |
+ mojom::PaymentManifestSection::New(); |
+ |
+ int index = 0; |
+ section->package_name = s.ColumnString(index++); |
+ section->version = s.ColumnInt64(index++); |
+ |
+ std::vector<uint8_t> finger_prints; |
+ if (!s.ColumnBlobAsVector(index, &finger_prints)) { |
+ NOTREACHED(); |
+ continue; |
please use gerrit instead
2017/04/06 14:35:29
Let's not read out only partial information from t
gogerald1
2017/04/06 16:42:09
Done.
|
+ } |
+ |
+ if (!DeserializeFingerPrints(finger_prints, |
+ section->sha256_cert_fingerprints)) { |
+ NOTREACHED(); |
+ continue; |
please use gerrit instead
2017/04/06 14:35:28
manifest.clear();
return manifest;
gogerald1
2017/04/06 16:42:09
Done.
|
+ } |
+ |
+ manifest.push_back(std::move(section)); |
+ } |
+ |
+ return manifest; |
+} |
+ |
+} // payments |