static PyObject *fs_root_paths_changed(FileSystemRootObject *self) { apr_pool_t *temp_pool; apr_hash_t *changed_paths; const char *key; apr_ssize_t klen; apr_hash_index_t *idx; PyObject *ret; temp_pool = Pool(NULL); if (temp_pool == NULL) return NULL; #if ONLY_SINCE_SVN(1, 6) RUN_SVN_WITH_POOL(temp_pool, svn_fs_paths_changed2(&changed_paths, self->root, temp_pool)); #else RUN_SVN_WITH_POOL(temp_pool, svn_fs_paths_changed(&changed_paths, self->root, temp_pool)); #endif ret = PyDict_New(); if (ret == NULL) { apr_pool_destroy(temp_pool); return NULL; } for (idx = apr_hash_first(temp_pool, changed_paths); idx != NULL; idx = apr_hash_next(idx)) { PyObject *py_val; #if ONLY_SINCE_SVN(1, 6) svn_fs_path_change2_t *val; #else svn_fs_path_change_t *val; #endif apr_hash_this(idx, (const void **)&key, &klen, (void **)&val); #if ONLY_SINCE_SVN(1, 6) py_val = py_fs_path_change2(val); #else py_val = py_fs_path_change(val); #endif if (py_val == NULL) { apr_pool_destroy(temp_pool); PyObject_Del(ret); return NULL; } if (PyDict_SetItemString(ret, key, py_val) != 0) { apr_pool_destroy(temp_pool); PyObject_Del(ret); Py_DECREF(py_val); return NULL; } Py_DECREF(py_val); } apr_pool_destroy(temp_pool); return ret; }
static svn_error_t * do_resources(const dav_svn_repos *repos, svn_fs_root_t *root, svn_revnum_t revision, ap_filter_t *output, apr_bucket_brigade *bb, apr_pool_t *pool) { apr_hash_t *changes; apr_hash_t *sent = apr_hash_make(pool); apr_hash_index_t *hi; apr_pool_t *subpool = svn_pool_create(pool); /* Fetch the paths changed in this revision. This will contain everything except otherwise-unchanged parent directories of added and deleted things. Also, note that deleted things don't merit responses of their own -- they are considered modifications to their parent. */ SVN_ERR(svn_fs_paths_changed(&changes, root, pool)); for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi)) { const void *key; void *val; const char *path; svn_fs_path_change_t *change; svn_boolean_t send_self; svn_boolean_t send_parent; svn_pool_clear(subpool); apr_hash_this(hi, &key, NULL, &val); path = key; change = val; /* Figure out who needs to get sent. */ switch (change->change_kind) { case svn_fs_path_change_delete: send_self = FALSE; send_parent = TRUE; break; case svn_fs_path_change_add: case svn_fs_path_change_replace: send_self = TRUE; send_parent = TRUE; break; case svn_fs_path_change_modify: default: send_self = TRUE; send_parent = FALSE; break; } if (send_self) { /* If we haven't already sent this path, send it (and then remember that we sent it). */ if (! apr_hash_get(sent, path, APR_HASH_KEY_STRING)) { svn_node_kind_t kind; SVN_ERR(svn_fs_check_path(&kind, root, path, subpool)); SVN_ERR(send_response(repos, root, path, kind == svn_node_dir ? TRUE : FALSE, output, bb, subpool)); apr_hash_set(sent, path, APR_HASH_KEY_STRING, (void *)1); } } if (send_parent) { /* If it hasn't already been sent, send the parent directory (and then remember that you sent it). Allocate parent in pool, not subpool, because it stays in the sent hash afterwards. */ const char *parent = svn_path_dirname(path, pool); if (! apr_hash_get(sent, parent, APR_HASH_KEY_STRING)) { SVN_ERR(send_response(repos, root, parent, TRUE, output, bb, subpool)); apr_hash_set(sent, parent, APR_HASH_KEY_STRING, (void *)1); } } } svn_pool_destroy(subpool); return SVN_NO_ERROR; }