Toyomasa Watarai
/
Mbed-example-WS-W27
Diff: simple-mbed-cloud-client/mbed-cloud-client/mbed-client/source/m2mcallbackstorage.cpp
- Revision:
- 0:119624335925
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple-mbed-cloud-client/mbed-cloud-client/mbed-client/source/m2mcallbackstorage.cpp Sat Jun 30 01:40:30 2018 +0000 @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2017 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "include/m2mcallbackstorage.h" + +#include <cstddef> + +// Dummy constructor, which does not init any value to something meaningful but needed for array construction. +// It is better to leave values unintialized, so the Valgrind will point out if the Vector is used without +// setting real values in there. +M2MCallbackAssociation::M2MCallbackAssociation() +{ +} + +M2MCallbackAssociation::M2MCallbackAssociation(const M2MBase *object, void *callback, M2MCallbackType type, void *client_args) +: _object(object), _callback(callback), _type(type), _client_args(client_args) +{ +} + +M2MCallbackStorage* M2MCallbackStorage::_static_instance = NULL; + +M2MCallbackStorage *M2MCallbackStorage::get_instance() +{ + if (M2MCallbackStorage::_static_instance == NULL) { + M2MCallbackStorage::_static_instance = new M2MCallbackStorage(); + } + return M2MCallbackStorage::_static_instance; +} + +void M2MCallbackStorage::delete_instance() +{ + delete M2MCallbackStorage::_static_instance; + M2MCallbackStorage::_static_instance = NULL; +} + +M2MCallbackStorage::~M2MCallbackStorage() +{ + // TODO: go through the list and delete all the FP<n> objects if there are any. + // On the other hand, if the system is done properly, each m2mobject should actually + // remove its callbacks from its destructor so there is nothing here to do +} + +bool M2MCallbackStorage::add_callback(const M2MBase &object, + void *callback, + M2MCallbackAssociation::M2MCallbackType type, + void *client_args) +{ + bool add_success = false; + M2MCallbackStorage* instance = get_instance(); + if (instance) { + + add_success = instance->do_add_callback(object, callback, type, client_args); + } + return add_success; +} + +bool M2MCallbackStorage::do_add_callback(const M2MBase &object, void *callback, M2MCallbackAssociation::M2MCallbackType type, void *client_args) +{ + bool add_success = false; + + // verify that the same callback is not re-added. + if (does_callback_exist(object, callback, type) == false) { + + const M2MCallbackAssociation association(&object, callback, type, client_args); + _callbacks.push_back(association); + add_success = true; + } + + return add_success; +} + +#if 0 // Functions not used currently +void M2MCallbackStorage::remove_callbacks(const M2MBase &object) +{ + // do not use the get_instance() here as it might create the instance + M2MCallbackStorage* instance = M2MCallbackStorage::_static_instance; + if (instance) { + + instance->do_remove_callbacks(object); + } +} + +void M2MCallbackStorage::do_remove_callbacks(const M2MBase &object) +{ + // find any association to given object and delete them from the vector + for (int index = 0; index < _callbacks.size();) { + if (_callbacks[index]._object == &object) { + _callbacks.erase(index); + } else { + index++; + } + } +} +#endif + +void* M2MCallbackStorage::remove_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) +{ + void* callback = NULL; + + // do not use the get_instance() here as it might create the instance + M2MCallbackStorage* instance = M2MCallbackStorage::_static_instance; + if (instance) { + + callback = instance->do_remove_callback(object, type); + } + return callback; +} + +void* M2MCallbackStorage::do_remove_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) +{ + void* callback = NULL; + for (int index = 0; index < _callbacks.size(); index++) { + + if ((_callbacks[index]._object == &object) && (_callbacks[index]._type == type)) { + callback = _callbacks[index]._callback; + _callbacks.erase(index); + break; + } + } + return callback; +} + +void* M2MCallbackStorage::get_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) +{ + void* callback = NULL; + const M2MCallbackStorage* instance = get_instance(); + if (instance) { + + callback = instance->do_get_callback(object, type); + } + return callback; +} + +void* M2MCallbackStorage::do_get_callback(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) const +{ + void* callback = NULL; + if (!_callbacks.empty()) { + M2MCallbackAssociationList::const_iterator it = _callbacks.begin(); + + for ( ; it != _callbacks.end(); it++ ) { + + if ((it->_object == &object) && (it->_type == type)) { + callback = it->_callback; + break; + } + } + } + return callback; +} + +M2MCallbackAssociation* M2MCallbackStorage::get_association_item(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) +{ + M2MCallbackAssociation* callback_association = NULL; + const M2MCallbackStorage* instance = get_instance(); + if (instance) { + + callback_association = instance->do_get_association_item(object, type); + } + return callback_association; +} + +M2MCallbackAssociation* M2MCallbackStorage::do_get_association_item(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) const +{ + M2MCallbackAssociation* callback_association = NULL; + if (!_callbacks.empty()) { + M2MCallbackAssociationList::const_iterator it = _callbacks.begin(); + + for ( ; it != _callbacks.end(); it++ ) { + + if ((it->_object == &object) && (it->_type == type)) { + callback_association = (M2MCallbackAssociation*)it; + break; + } + } + } + return callback_association; +} + +bool M2MCallbackStorage::does_callback_exist(const M2MBase &object, M2MCallbackAssociation::M2MCallbackType type) +{ + bool found = false; + if (get_callback(object, type) != NULL) { + found = true; + } + return found; +} + +bool M2MCallbackStorage::does_callback_exist(const M2MBase &object, void *callback, M2MCallbackAssociation::M2MCallbackType type) const +{ + bool match_found = false; + + if (!_callbacks.empty()) { + M2MCallbackAssociationList::const_iterator it = _callbacks.begin(); + + for ( ; it != _callbacks.end(); it++ ) { + + if ((it->_object == &object) && (it->_callback == callback) && (it->_type == type)) { + match_found = true; + break; + } + } + } + + return match_found; +}