void eraseHeap(GenericHeap * hp, void (*freeFn) (void*)) { if(hp==NULL) { printf("Error: tried to erase NULL heap\n"); return; } if(freeFn==NULL) { printf("Error: called eraseHeap with NULL function pointer\n"); return; } int i; //remember hp->container[0] is always null for(i=1; i<=hp->lastIndex; ++i) { if(hp->container[i] ==NULL) { printf("Warning: eraseHeap found NULL data and ignored"); } else { freeFn(hp->container[i]); } } free(hp->container); free(hp); }
//--------------------------------------------------------------------- // free all fxp_names + my_fxp_names static void freeMfn(my_fxp_names * dir) { if (!dir) return; for (int i = 0; i < dir->nnames; i++) { freeFn(dir->names[i]); } free(dir); }
/** * @brief Clean up and free all memory managed by the Schema * * Note that any Subschema pointers created and returned by this Schema * should be considered invalid. */ virtual ~Schema() { sharedEmptySubschema->~Subschema(); freeFn((void*)(sharedEmptySubschema)); sharedEmptySubschema = NULL; try { for (std::set<Subschema *>::iterator itr = subschemaSet.begin(); itr != subschemaSet.end(); ++itr) { Subschema *subschema = *itr; subschema->~Subschema(); freeFn(subschema); } } catch (const std::exception &e) { fprintf(stderr, "Caught an exception while destroying Schema: %s", e.what()); } }
//--------------------------------------------------------------------- // remove a remote folder bool Server::cmdRmDir(bstring const & remotePath) { bstring path; splitPath(path, remotePath); invalidateDirContent(path); bstring cmd = bstring(TEXT("rmdir \"")) + remotePath + TEXT("\""); if (!doCommand(cmd)) return false; freeFn(removeFile(remotePath)); return true; }
Subschema *newSubschema() { void *ptr = allocFn(sizeof(Subschema)); if (!ptr) { throw std::runtime_error( "Failed to allocate memory for shared empty sub-schema"); } try { return new (ptr) Subschema(); } catch (...) { freeFn(ptr); throw; } }
/** * @brief Create a new Subschema instance that is owned by this Schema * * @returns const pointer to the new Subschema instance */ const Subschema * createSubschema() { Subschema *subschema = newSubschema(); try { if (!subschemaSet.insert(subschema).second) { throw std::runtime_error( "Failed to store pointer for new sub-schema"); } } catch (...) { subschema->~Subschema(); freeFn(subschema); throw; } return subschema; }
//--------------------------------------------------------------------- // move a remote file to a remote file bool Server::cmdMove(bstring const & oldRemotePath, bstring const & newRemotePath) { bstring cmd = bstring(TEXT("mv \"")) + oldRemotePath + TEXT("\" \"") + newRemotePath + TEXT("\""); if (!doCommand(cmd)) return false; fxp_name * fn = removeFile(oldRemotePath); if (fn) { FILETIME ft; UnixTimeToFileTime(fn->attrs.mtime, &ft); insertFile(newRemotePath, &ft, fn->attrs.size.lo, fn->attrs.size.hi, fn->longname[0]); freeFn(fn); } else { bstring path; splitPath(path, newRemotePath); invalidateDirContent(path); } return true; }
//--------------------------------------------------------------------- // update the file attributes void Server::updateFileAttr(bstring const & path, bstring const & file, bstring const & attrs) { DirCache::iterator i = dirCache.find(path); if (i == dirCache.end()) return; my_fxp_names * dir = i->second; int count = dir->nnames; for (int i = 0; i < count; ++i) { fxp_name * fn = dir->names[i]; #ifdef UNICODE if (file == fn->ucFilename) { #else if (file == fn->filename) { #endif // got it fn->attrs.permissions = bstrtol(attrs.c_str(), '\0', 8); return; } } } //--------------------------------------------------------------------- // CT // init with zeros Server::Server(bstring const & serverName) : name(serverName), currentMapper(0), disableMtime(false), myCfg(0) { } //--------------------------------------------------------------------- // free one fxp_name static void freeFn(fxp_name * fn) { if (!fn) return; free(fn->filename); free(fn->longname); free(fn); } //--------------------------------------------------------------------- // free all fxp_names + my_fxp_names static void freeMfn(my_fxp_names * dir) { if (!dir) return; for (int i = 0; i < dir->nnames; i++) { freeFn(dir->names[i]); } free(dir); } //--------------------------------------------------------------------- // DT // free all cached structures Server::~Server() { if (currentMapper && currentMapper->hDll && !currentMapper->disconnected()) { currentMapper->disconnect(); } delete currentMapper; clearDirCache(); delete myCfg; } bool Server::connect() { // Guard guard(this); // return guard.isConnected(); return true; } //--------------------------------------------------------------------- // clear the folder chache void Server::clearDirCache() { for (DirCache::iterator i = dirCache.begin(); i != dirCache.end(); ++i) { my_fxp_names * dir = i->second; freeMfn(dir); } dirCache.clear(); } //--------------------------------------------------------------------- // performs a server lookup by evaluating the remote path // on success the remote path is also set Server * Server::findServer(bstring & remotePath, bchar const * const fullPath) { bstring serverName = *fullPath == TEXT('\\') ? fullPath + 1 : fullPath; int slash = (int) serverName.find_first_of(TEXT('\\')); if (slash > 0) { remotePath = serverName.substr(slash); for (bstring::iterator i = remotePath.begin(); i != remotePath.end(); ++i) { if (*i == TEXT('\\')) *i = '/'; } serverName = serverName.substr(0, slash); } else { remotePath = TEXT("/"); } ServerMap::const_iterator i = serverMap.find(serverName); Server * server; if (i != serverMap.end()) { server = i->second; } else { server = new Server(serverName); serverMap.insert(std::make_pair(serverName, server)); } return server; }