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 3// found in the LICENSE file. 4 5#include "google_apis/gcm/engine/account_mapping.h" 6 7#include "base/strings/string_number_conversions.h" 8#include "base/strings/string_util.h" 9 10namespace gcm { 11 12namespace { 13 14const char kSeparator[] = "&"; 15const uint32 kEmailIndex = 0; 16const uint32 kStatusIndex = 1; 17const uint32 kStatusChangeTimestampIndex = 2; 18const uint32 kSizeWithNoMessage = kStatusChangeTimestampIndex + 1; 19const uint32 kMessageIdIndex = 3; 20const uint32 kSizeWithMessage = kMessageIdIndex + 1; 21 22const char kStatusNew[] = "new"; 23const char kStatusAdding[] = "adding"; 24const char kStatusMapped[] = "mapped"; 25const char kStatusRemoving[] = "removing"; 26 27std::string StatusToString(AccountMapping::MappingStatus status) { 28 switch (status) { 29 case AccountMapping::NEW: 30 return kStatusNew; 31 case AccountMapping::ADDING: 32 return kStatusAdding; 33 case AccountMapping::MAPPED: 34 return kStatusMapped; 35 case AccountMapping::REMOVING: 36 return kStatusRemoving; 37 default: 38 NOTREACHED(); 39 } 40 return std::string(); 41} 42 43bool StringToStatus(const std::string& status_str, 44 AccountMapping::MappingStatus* status) { 45 if (status_str.compare(kStatusAdding) == 0) 46 *status = AccountMapping::ADDING; 47 else if (status_str.compare(kStatusMapped) == 0) 48 *status = AccountMapping::MAPPED; 49 else if (status_str.compare(kStatusRemoving) == 0) 50 *status = AccountMapping::REMOVING; 51 else if (status_str.compare(kStatusNew) == 0) 52 *status = AccountMapping::NEW; 53 else 54 return false; 55 56 return true; 57} 58 59} // namespace 60 61AccountMapping::AccountMapping() : status(NEW) { 62} 63 64AccountMapping::~AccountMapping() { 65} 66 67std::string AccountMapping::SerializeAsString() const { 68 std::string value; 69 value.append(email); 70 value.append(kSeparator); 71 value.append(StatusToString(status)); 72 value.append(kSeparator); 73 value.append(base::Int64ToString(status_change_timestamp.ToInternalValue())); 74 if (!last_message_id.empty()) { 75 value.append(kSeparator); 76 value.append(last_message_id); 77 } 78 79 return value; 80} 81 82bool AccountMapping::ParseFromString(const std::string& value) { 83 std::vector<std::string> values; 84 Tokenize(value, kSeparator, &values); 85 if (values.size() != kSizeWithNoMessage && 86 values.size() != kSizeWithMessage) { 87 return false; 88 } 89 90 if (values[kEmailIndex].empty() || 91 values[kStatusChangeTimestampIndex].empty() || 92 values[kStatusIndex].empty()) { 93 return false; 94 } 95 96 if (values.size() == kSizeWithMessage && values[kMessageIdIndex].empty()) 97 return false; 98 99 MappingStatus temp_status; 100 if (!StringToStatus(values[kStatusIndex], &temp_status)) 101 return false; 102 103 if (values.size() == kSizeWithNoMessage && 104 (temp_status == REMOVING || temp_status == ADDING)) { 105 return false; 106 } 107 108 int64 status_change_ts_internal = 0LL; 109 if (!base::StringToInt64(values[kStatusChangeTimestampIndex], 110 &status_change_ts_internal)) { 111 return false; 112 } 113 114 status_change_timestamp = 115 base::Time::FromInternalValue(status_change_ts_internal); 116 status = temp_status; 117 email = values[kEmailIndex]; 118 access_token.clear(); 119 120 if (values.size() == kSizeWithMessage) 121 last_message_id = values[kMessageIdIndex]; 122 else 123 last_message_id.clear(); 124 125 return true; 126} 127 128} // namespace gcm 129