| // Copyright (c) 2012 The Chromium OS 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 "prop_provider.h" |
| |
| #include <iostream> |
| |
| #include <jsoncpp/json/reader.h> |
| #include <jsoncpp/json/value.h> |
| |
| #include "util.h" |
| |
| using Json::Value; |
| |
| namespace replay { |
| |
| // Implementation of GesturesProp for all numerical types |
| template<typename Type> |
| class GesturesPropImpl : public GesturesProp { |
| public: |
| GesturesPropImpl(const char* name, Type* value) |
| : name_(name), value_(value) { |
| } |
| |
| virtual void SetValue(const std::string& value) { |
| *value_ = replay_lexical_cast<Type>(value); |
| } |
| |
| virtual std::string GetName() { |
| return name_; |
| } |
| |
| private: |
| std::string name_; |
| Type* value_; |
| }; |
| |
| // GesturesProp implementation for string properties. |
| // This requires a local string instance to store a copy of the value. |
| template<> |
| class GesturesPropImpl<const char*> : public GesturesProp { |
| public: |
| GesturesPropImpl(const char* name, const char** value) |
| : name_(name), value_(value) { |
| } |
| |
| virtual void SetValue(const std::string& value) { |
| local_ = value; |
| *value_ = local_.c_str(); |
| } |
| |
| virtual std::string GetName() { |
| return name_; |
| } |
| |
| private: |
| std::string name_; |
| const char** value_; |
| std::string local_; |
| }; |
| |
| PropProvider::PropProvider() { |
| } |
| |
| PropProvider::~PropProvider() { |
| typedef std::map<std::string, GesturesProp*>::iterator iter_t; |
| for (iter_t iter = properties_.begin(); iter != properties_.end(); ++iter) { |
| delete iter->second; |
| } |
| properties_.clear(); |
| } |
| |
| bool PropProvider::CheckIntegrity() { |
| if (properties_cache_.size() > 0) { |
| typedef std::map<std::string, std::string>::iterator iter_t; |
| for (iter_t iter = properties_cache_.begin(); |
| iter != properties_cache_.end(); ++iter) { |
| std::cerr << "Unknown Property: " << iter->first << std::endl; |
| } |
| return false; |
| } |
| return true; |
| } |
| |
| template<typename Type> |
| GesturesProp* PropProvider::CreateProp(const char* name, Type* loc, |
| size_t count, const Type* init) { |
| GesturesProp* prop = new GesturesPropImpl<Type>(name, loc); |
| if (properties_cache_.find(name) != properties_cache_.end()) { |
| prop->SetValue(properties_cache_[name]); |
| properties_cache_.erase(name); |
| } else { |
| for (size_t i = 0; i < count; i++) |
| loc[i] = init[i]; |
| } |
| properties_[std::string(name)] = prop; |
| return prop; |
| } |
| |
| GesturesProp* PropProvider::GetPropSafe(const std::string& name) { |
| GesturesProp* prop = properties_[name]; |
| if (!prop) { |
| std::cerr << "Property " << name << " does not exist." << std::endl; |
| exit(-1); |
| } |
| return prop; |
| } |
| |
| bool PropProvider::Load(const std::string& data) { |
| Json::Reader reader; |
| Value root; |
| if (!reader.parse(data, root, false)) { |
| std::cerr << "Parse failed" << reader.getFormattedErrorMessages() |
| << std::endl; |
| return false; |
| } |
| |
| for (std::string key: root.getMemberNames()) { |
| const Value& value = root[key]; |
| |
| std::string stringVal; |
| switch (value.type()) { |
| case Json::intValue: { |
| int intVal = value.asInt(); |
| stringVal = replay_lexical_cast<std::string>(intVal); |
| break; |
| } |
| case Json::booleanValue: { |
| bool boolVal = value.asBool(); |
| stringVal = replay_lexical_cast<std::string>(boolVal); |
| break; |
| } |
| case Json::realValue: { |
| double doubleVal = value.asDouble(); |
| stringVal = replay_lexical_cast<std::string>(doubleVal); |
| break; |
| } |
| case Json::stringValue: { |
| stringVal = value.asString(); |
| break; |
| } |
| default: |
| std::cerr << "Invalid property type: " << key << std::endl; |
| std::cerr << "Expected Integer, Boolean, Double or String" << std::endl; |
| return false; |
| } |
| |
| if (properties_.find(key) == properties_.end()) { |
| properties_cache_[key] = stringVal; |
| } else { |
| GetPropSafe(key)->SetValue(stringVal); |
| } |
| } |
| return true; |
| } |
| |
| void PropProvider::Free(GesturesProp* prop) { |
| properties_.erase(prop->GetName()); |
| } |
| |
| // Wrapper method to create properties for the gestures library. |
| template<typename Type> |
| GesturesProp* PropProviderCreate(void* data, const char* name, Type* loc, |
| size_t count, const Type* init) { |
| PropProvider* pp = static_cast<PropProvider*>(data); |
| return pp->CreateProp<Type>(name, loc, count, init); |
| } |
| |
| GesturesProp* PropProviderCreateString(void* data, const char* name, |
| const char** loc, |
| const char* const init) { |
| PropProvider* pp = static_cast<PropProvider*>(data); |
| return pp->CreateProp<const char*>(name, loc, static_cast<size_t>(1), &init); |
| } |
| |
| // Dummy method. This provider does not support Get/Set handlers. |
| void PropProviderRegisterHandlers(void* data, GesturesProp* prop, |
| void* handler_data, |
| GesturesPropGetHandler getter, |
| GesturesPropSetHandler setter) { |
| } |
| |
| // Wrapper method to free properties for the gestures library. |
| void PropProviderFree(void* data, GesturesProp* prop) { |
| PropProvider* pp = static_cast<PropProvider*>(data); |
| return pp->Free(prop); |
| } |
| |
| GesturesPropProvider CPropProvider = { |
| PropProviderCreate<int>, |
| PropProviderCreate<short>, |
| PropProviderCreate<GesturesPropBool>, |
| PropProviderCreateString, |
| PropProviderCreate<double>, |
| PropProviderRegisterHandlers, |
| PropProviderFree |
| }; |
| |
| } // namespace replay |
| |