blob: f32c7cc35f2240435909c0f2754de82d5fbbe6d2 [file] [log] [blame]
// 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