Home | History | Annotate | Download | only in engine
      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 
     10 namespace gcm {
     11 
     12 namespace {
     13 
     14 const char kSeparator[] = "&";
     15 const uint32 kEmailIndex = 0;
     16 const uint32 kStatusIndex = 1;
     17 const uint32 kStatusChangeTimestampIndex = 2;
     18 const uint32 kSizeWithNoMessage = kStatusChangeTimestampIndex + 1;
     19 const uint32 kMessageIdIndex = 3;
     20 const uint32 kSizeWithMessage = kMessageIdIndex + 1;
     21 
     22 const char kStatusNew[] = "new";
     23 const char kStatusAdding[] = "adding";
     24 const char kStatusMapped[] = "mapped";
     25 const char kStatusRemoving[] = "removing";
     26 
     27 std::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 
     43 bool 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 
     61 AccountMapping::AccountMapping() : status(NEW) {
     62 }
     63 
     64 AccountMapping::~AccountMapping() {
     65 }
     66 
     67 std::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 
     82 bool 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