//============================================================================= // METHOD : SPELLwsListDataHandler::read() //============================================================================= void SPELLwsListDataHandler::read() { // Load the number of items unsigned int numItems = getStorage()->loadLong(); // Create a list PyObject* listObject = PyList_New(numItems); for( unsigned int index = 0; index < numItems; index++) { // Load the item code SPELLwsData::Code code = loadDataCode(); // Create an appropriate handler SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(code); handler->setStorage(getStorage()); // Read the data handler->read(); // Add the item to the list PyList_SetItem(listObject, index, handler->getObject()); delete handler; } // Set it as associated object setObject( listObject ); }
//============================================================================= // METHOD : SPELLwsListDataHandler::write() //============================================================================= void SPELLwsListDataHandler::write() { assert( PyList_Check(getObject())); unsigned int numItems = PyList_Size( getObject() ); // Store the number of items getStorage()->storeLong( (long) numItems ); // Store each list item for( unsigned int index = 0; index < numItems; index++) { PyObject* item = PyList_GetItem( getObject(), index ); try { SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(item); handler->setStorage(getStorage()); // Store the item data code. We need it for reading operation, in order to // know which type of handler to create. handler->storeDataCode(); // IMPORTANT in the case of lists and dictionaries, we want to be able to continue // the storage evenif there is a problem in the handler processing at this point. // If that is the case, a fake empty object will be replaced by the object being // processed by the handler, and the dumping of this collection will continue. try { // Store the data handler->write(); } catch(SPELLcoreException& ex) { std::string msg = "WARNING! Storage of element " + ISTR(index) + " failed: " + ex.what(); LOG_WARN(msg); std::cerr << msg << std::endl; storeFakeObject( handler->getCode() ); } delete handler; } catch(SPELLcoreException& ex) { std::string msg = "WARNING! Failed to create data handler: " + ex.what(); LOG_WARN(msg); storeFakeObject( SPELLwsData::DATA_NONE ); } } }
//============================================================================= // METHOD : SPELLwsDictDataHandler::write() //============================================================================= void SPELLwsDictDataHandler::write() { if (getObject() == NULL) { getStorage()->storeLong( -1 ); return; } assert( PyDict_Check(getObject())); SPELLpyHandle keys = PyDict_Keys( getObject() ); unsigned int numItems = PyList_Size( keys.get() ); DEBUG("[DDH] Storing dictionary items (total " + ISTR(numItems) + ") address " + PSTR(getObject())); PyObject* key = NULL; PyObject* item = NULL; long toStore = 0; // Calculate the number of items to store // Store each list item DEBUG("[DDH] Keys of the dictionary:"); for( unsigned int index = 0; index < numItems; index++) { key = PyList_GetItem( keys.get(), index ); item = PyDict_GetItem( getObject(), key ); if (SPELLwsWarmStartImpl::shouldFilter(key,item)) { continue; } else { DEBUG(" - " + PYSSTR(key)); } toStore++; } DEBUG("[DDH] Will store " + ISTR(toStore) + " keys"); // Store the number of items getStorage()->storeLong( (long) toStore ); DEBUG("[DDH] Start checking items"); if (toStore>0) { // Store each list item for( unsigned int index = 0; index < numItems; index++) { key = PyList_GetItem( keys.get(), index ); item = PyDict_GetItem( getObject(), key ); DEBUG("[DDH] Checking item " + PYCREPR(key)); // Do not consider filtered values if (SPELLwsWarmStartImpl::shouldFilter(key,item)) continue; SPELLpythonHelper::instance().checkError(); DEBUG(" [DDH] Key index " + ISTR(index)); DEBUG(" [DDH] Key to use" + PYREPR(key)); DEBUG(" [DDH] Item type:" + PYREPR(PyObject_Type(item))); // Handler for the key SPELLwsObjectDataHandler keyHandler(key); keyHandler.setStorage(getStorage()); DEBUG(" [DDH] Creating handler"); // Create a handler for the item SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(item); handler->setStorage(getStorage()); // Store the key DEBUG(" [DDH] Storing key: " + PYREPR(key)); keyHandler.write(); // Store the item data code in order to recognise it later DEBUG(" [DDH] Storing data code: " + SPELLwsData::codeStr(handler->getCode())); handler->storeDataCode(); // IMPORTANT in the case of lists and dictionaries, we want to be able to continue // the storage even if there is a problem in the handler processing at this point. // If that is the case, a fake empty object will be replaced by the object being // processed by the handler, and the dumping of this collection will continue. try { if (handler->getCode() == SPELLwsData::DATA_CUSTOM_TYPE ) { std::string msg = "WARNING! warm start not supported for custom Python types (" + PYREPR(key) + "=" + PYREPR(item) + ")"; LOG_WARN(msg); SPELLexecutor::instance().getCIF().warning(msg); storeFakeObject( SPELLwsData::DATA_NONE ); } else { // Store the value DEBUG(" [DDH] Storing value: " + PYREPR(item)); handler->write(); DEBUG(" [DDH] Storing value done"); } } catch(SPELLcoreException& ex) { std::string msg = "WARNING! WS storage of element " + ISTR(index) + " failed: " + ex.what(); LOG_WARN(msg); SPELLexecutor::instance().getCIF().warning(msg); storeFakeObject( handler->getCode() ); } delete handler; } } DEBUG("[DDH] Storing dictionary done"); }
//============================================================================= // METHOD : SPELLwsDictDataHandler::read() //============================================================================= void SPELLwsDictDataHandler::read() { DEBUG("[DDH] Loading dictionary items"); // Load the number of items int numItems = getStorage()->loadLong(); DEBUG("[DDH] Number of items " + ISTR(numItems)); if (numItems == -1) { setObject(NULL); return; } // Create a dictionary PyObject* dictObject = PyDict_New(); for( unsigned int index = 0; index < (unsigned) numItems; index++) { // We know that first an Object comes, as the key. So make the handler directly. SPELLwsObjectDataHandler keyHandler(NULL); keyHandler.setStorage(getStorage()); DEBUG(" [DDH] Loading key"); keyHandler.read(); PyObject* key = keyHandler.getObject(); DEBUG(" [DDH] Loaded key " + PYREPR(key)); // Load the item code DEBUG(" [DDH] Loading data code"); SPELLwsData::Code code = loadDataCode(); DEBUG(" [DDH] Loaded data code " + SPELLwsData::codeStr(code)); if (code == SPELLwsData::DATA_CUSTOM_TYPE ) { std::string msg = "WARNING! warm start not supported for custom Python types (" + PYREPR(key) + ")"; LOG_WARN(msg); SPELLexecutor::instance().getCIF().warning(msg); getStorage()->loadObject(); // Load none PyDict_SetItem(dictObject, key, Py_None); } else { // Create an appropriate handler SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(code); handler->setStorage(getStorage()); try { // Read the data DEBUG(" [DDH] Loading value"); handler->read(); DEBUG(" [DDH] Value loaded " + PYREPR(handler->getObject())); // Add the item to the dictionary PyDict_SetItem(dictObject, key, handler->getObject()); } catch(SPELLcoreException& ex) { std::string msg = "Failed to recover dictionary item " + PYREPR(key) + ": " + ex.what(); LOG_WARN(msg); SPELLexecutor::instance().getCIF().warning(msg); PyDict_SetItem(dictObject, key, Py_None); } delete handler; DEBUG(" [DDH] "); } } DEBUG("[DDH] Dictionary loaded"); // Set it as associated object setObject( dictObject ); }