1 //
2 // ====================================================================
3 // Copyright (c) 2003-2009 Barry A Scott. All rights reserved.
4 //
5 // This software is licensed as described in the file LICENSE.txt,
6 // which you should have received as part of this distribution.
7 //
8 // ====================================================================
9 //
10 #include "pysvn_svnenv.hpp"
11 #include "svn_config.h"
12 #include "svn_pools.h"
13 #include "CXX/Objects.hxx"
14
15 //--------------------------------------------------------------------------------
16 //
17 // SvnException
18 //
19 //--------------------------------------------------------------------------------
SvnException(svn_error_t * error)20 SvnException::SvnException( svn_error_t *error )
21 : m_message()
22 , m_exception_arg()
23 {
24 std::string whole_message;
25
26 // set the error to be a list of (code, message) tuples
27 Py::List error_list;
28 while( error != NULL )
29 {
30 Py::Tuple t( 2 );
31
32 if( !whole_message.empty() )
33 {
34 whole_message += "\n";
35 }
36
37 if( error->message != NULL )
38 {
39 t[0] = Py::String( error->message );
40 whole_message += error->message;
41 }
42 else
43 {
44 char buffer[256];
45 buffer[0] = '\0';
46
47 svn_strerror( error->apr_err, buffer, sizeof( buffer ) );
48 whole_message += buffer;
49 t[0] = Py::String( buffer );
50 }
51 t[1] = Py::Int( error->apr_err );
52 error_list.append( t );
53
54 error = error->child;
55 }
56 m_message = Py::String( whole_message );
57 Py::Tuple arg_list(2);
58 arg_list[0] = m_message;
59 arg_list[1] = error_list;
60
61 m_exception_arg = arg_list;
62
63 svn_error_clear( error );
64 }
65
SvnException(const SvnException & other)66 SvnException::SvnException( const SvnException &other )
67 : m_code( other.m_code )
68 , m_message( other.m_message )
69 , m_exception_arg( other.m_exception_arg )
70 { }
71
~SvnException()72 SvnException::~SvnException()
73 { }
74
message()75 Py::String &SvnException::message()
76 {
77 return m_message;
78 }
79
code()80 apr_status_t SvnException::code()
81 {
82 return m_code;
83 }
84
pythonExceptionArg(int style)85 Py::Object &SvnException::pythonExceptionArg( int style )
86 {
87 if( style == 1 )
88 {
89 return m_exception_arg;
90 }
91 else
92 {
93 return m_message;
94 }
95 }
96
97 //--------------------------------------------------------------------------------
98 //
99 // SvnContext
100 //
101 //--------------------------------------------------------------------------------
102 #if defined( PYSVN_HAS_CONTEXT_LOG_MSG2 )
handlerLogMsg2(const char ** log_msg,const char ** tmp_file,const apr_array_header_t * commit_items,void * baton,apr_pool_t * pool)103 extern "C" svn_error_t *handlerLogMsg2
104 (
105 const char **log_msg,
106 const char **tmp_file,
107 const apr_array_header_t *commit_items,
108 void *baton,
109 apr_pool_t *pool
110 )
111 {
112 SvnContext *context = SvnContext::castBaton( baton );
113
114 std::string msg;
115
116 if (!context->contextGetLogMessage( msg ) )
117 return svn_error_create( SVN_ERR_CANCELLED, NULL, "" );
118
119 *log_msg = svn_string_ncreate( msg.data(), msg.length(), pool )->data;
120 *tmp_file = NULL;
121
122 return SVN_NO_ERROR;
123 }
124 #else
handlerLogMsg(const char ** log_msg,const char ** tmp_file,apr_array_header_t * commit_items,void * baton,apr_pool_t * pool)125 extern "C" svn_error_t *handlerLogMsg
126 (
127 const char **log_msg,
128 const char **tmp_file,
129 apr_array_header_t *commit_items,
130 void *baton,
131 apr_pool_t *pool
132 )
133 {
134 SvnContext *context = SvnContext::castBaton( baton );
135
136 std::string msg;
137
138 if (!context->contextGetLogMessage( msg ) )
139 return svn_error_create( SVN_ERR_CANCELLED, NULL, "" );
140
141 *log_msg = svn_string_ncreate( msg.data(), msg.length(), pool )->data;
142 *tmp_file = NULL;
143
144 return SVN_NO_ERROR;
145 }
146 #endif
147
148 #if defined( PYSVN_HAS_CONTEXT_NOTIFY2 )
handlerNotify2(void * baton,const svn_wc_notify_t * notify,apr_pool_t * pool)149 extern "C" void handlerNotify2
150 (
151 void *baton,
152 const svn_wc_notify_t *notify,
153 apr_pool_t *pool
154 )
155 {
156 SvnContext *context = SvnContext::castBaton( baton );
157
158 context->contextNotify2( notify, pool );
159 }
160 #else
handlerNotify(void * baton,const char * path,svn_wc_notify_action_t action,svn_node_kind_t kind,const char * mime_type,svn_wc_notify_state_t content_state,svn_wc_notify_state_t prop_state,svn_revnum_t revision)161 extern "C" void handlerNotify
162 (
163 void * baton,
164 const char *path,
165 svn_wc_notify_action_t action,
166 svn_node_kind_t kind,
167 const char *mime_type,
168 svn_wc_notify_state_t content_state,
169 svn_wc_notify_state_t prop_state,
170 svn_revnum_t revision
171 )
172 {
173 pysvn_bpt();
174
175 SvnContext *context = SvnContext::castBaton( baton );
176
177 context->contextNotify( path, action, kind, mime_type, content_state, prop_state, revision );
178 }
179 #endif
180
181 #if defined( PYSVN_HAS_CONTEXT_PROGRESS )
handlerProgress(apr_off_t progress,apr_off_t total,void * baton,apr_pool_t * pool)182 extern "C" void handlerProgress
183 (
184 apr_off_t progress,
185 apr_off_t total,
186 void *baton,
187 apr_pool_t *pool
188 )
189 {
190 SvnContext *context = SvnContext::castBaton( baton );
191
192 context->contextProgress( progress, total );
193 }
194 #endif
195
196 #if defined( PYSVN_HAS_SVN_CLIENT_CTX_T__CONFLICT_FUNC )
handlerConflictResolver(svn_wc_conflict_result_t ** result,const svn_wc_conflict_description_t * description,void * baton,apr_pool_t * pool)197 extern "C" svn_error_t *handlerConflictResolver
198 (
199 svn_wc_conflict_result_t **result,
200 const svn_wc_conflict_description_t *description,
201 void *baton,
202 apr_pool_t *pool
203 )
204 {
205 SvnContext *context = SvnContext::castBaton( baton );
206
207 if( context->contextConflictResolver( result, description, pool ) )
208 return SVN_NO_ERROR;
209 else
210 return svn_error_create( SVN_ERR_CANCELLED, NULL, "cancelled by user" );
211 }
212 #endif
213
handlerCancel(void * baton)214 extern "C" svn_error_t *handlerCancel
215 (
216 void * baton
217 )
218 {
219 SvnContext *context = SvnContext::castBaton( baton );
220
221 if( context->contextCancel() )
222 return svn_error_create( SVN_ERR_CANCELLED, NULL, "cancelled by user" );
223 else
224 return SVN_NO_ERROR;
225 }
226
handlerSimplePrompt(svn_auth_cred_simple_t ** cred,void * baton,const char * a_realm,const char * a_username,svn_boolean_t a_may_save,apr_pool_t * pool)227 extern "C" svn_error_t *handlerSimplePrompt
228 (
229 svn_auth_cred_simple_t **cred,
230 void *baton,
231 const char *a_realm,
232 const char *a_username,
233 svn_boolean_t a_may_save,
234 apr_pool_t *pool
235 )
236 {
237 SvnContext *context = SvnContext::castBaton( baton );
238
239 bool may_save = a_may_save != 0;
240
241 if( a_realm == NULL )
242 a_realm = "";
243 if( a_username == NULL )
244 a_username = "";
245 std::string realm( a_realm );
246 std::string username( a_username );
247 std::string password;
248
249 if( !context->contextGetLogin( realm, username, password, may_save ) )
250 return svn_error_create( SVN_ERR_CANCELLED, NULL, "" );
251
252 svn_auth_cred_simple_t *lcred = (svn_auth_cred_simple_t *)apr_palloc( pool, sizeof( svn_auth_cred_simple_t ) );
253 lcred->username = svn_string_ncreate( username.data(), username.length(), pool )->data;
254 lcred->password = svn_string_ncreate( password.data(), password.length(), pool )->data;
255
256 // tell svn if the credentials need to be saved
257 lcred->may_save = may_save;
258 *cred = lcred;
259
260 return SVN_NO_ERROR;
261 }
262
handlerSslServerTrustPrompt(svn_auth_cred_ssl_server_trust_t ** cred,void * baton,const char * a_realm,apr_uint32_t failures,const svn_auth_ssl_server_cert_info_t * info,svn_boolean_t may_save,apr_pool_t * pool)263 extern "C" svn_error_t *handlerSslServerTrustPrompt
264 (
265 svn_auth_cred_ssl_server_trust_t **cred,
266 void *baton,
267 const char *a_realm,
268 apr_uint32_t failures,
269 const svn_auth_ssl_server_cert_info_t *info,
270 svn_boolean_t may_save,
271 apr_pool_t *pool
272 )
273 {
274 SvnContext *context = SvnContext::castBaton( baton );
275
276 apr_uint32_t accepted_failures = failures;
277 bool accept_permanently = true;
278
279 if( a_realm == NULL )
280 a_realm = "";
281 std::string realm( a_realm );
282 if( !context->contextSslServerTrustPrompt( *info, realm, accepted_failures, accept_permanently ) )
283 {
284 *cred = NULL;
285
286 return SVN_NO_ERROR;
287 }
288
289 svn_auth_cred_ssl_server_trust_t *new_cred = (svn_auth_cred_ssl_server_trust_t *)
290 apr_palloc( pool, sizeof (svn_auth_cred_ssl_server_trust_t) );
291
292 if( accept_permanently )
293 {
294 new_cred->may_save = 1;
295 }
296
297 new_cred->accepted_failures = accepted_failures;
298
299 *cred = new_cred;
300
301 return SVN_NO_ERROR;
302 }
303
handlerSslClientCertPrompt(svn_auth_cred_ssl_client_cert_t ** cred,void * baton,const char * a_realm,svn_boolean_t a_may_save,apr_pool_t * pool)304 extern "C" svn_error_t *handlerSslClientCertPrompt
305 (
306 svn_auth_cred_ssl_client_cert_t **cred,
307 void *baton,
308 const char *a_realm,
309 svn_boolean_t a_may_save,
310 apr_pool_t *pool
311 )
312 {
313 SvnContext *context = SvnContext::castBaton( baton );
314
315 if( a_realm == NULL )
316 a_realm = "";
317 std::string realm( a_realm );
318 bool may_save = a_may_save != 0;
319 std::string cert_file;
320 if( !context->contextSslClientCertPrompt( cert_file, realm, may_save ) )
321 return svn_error_create (SVN_ERR_CANCELLED, NULL, "");
322
323 svn_auth_cred_ssl_client_cert_t *new_cred = (svn_auth_cred_ssl_client_cert_t*)
324 apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_t));
325
326 new_cred->cert_file = svn_string_ncreate( cert_file.data(), cert_file.length(), pool )->data;
327 new_cred->may_save = may_save;
328
329 *cred = new_cred;
330
331 return SVN_NO_ERROR;
332 }
333
handlerSslClientCertPwPrompt(svn_auth_cred_ssl_client_cert_pw_t ** cred,void * baton,const char * a_realm,svn_boolean_t a_may_save,apr_pool_t * pool)334 extern "C" svn_error_t *handlerSslClientCertPwPrompt
335 (
336 svn_auth_cred_ssl_client_cert_pw_t **cred,
337 void *baton,
338 const char *a_realm,
339 svn_boolean_t a_may_save,
340 apr_pool_t *pool
341 )
342 {
343 SvnContext *context = SvnContext::castBaton( baton );
344
345 if( a_realm == NULL )
346 a_realm = "";
347 std::string realm( a_realm );
348
349 std::string password;
350 bool may_save = a_may_save != 0;
351 if( !context->contextSslClientCertPwPrompt( password, realm, may_save ) )
352 return svn_error_create( SVN_ERR_CANCELLED, NULL, "" );
353
354 svn_auth_cred_ssl_client_cert_pw_t *new_cred = (svn_auth_cred_ssl_client_cert_pw_t *)
355 apr_palloc (pool, sizeof (svn_auth_cred_ssl_client_cert_pw_t));
356
357 new_cred->password = svn_string_ncreate( password.data(), password.length(), pool )->data;
358 new_cred->may_save = may_save;
359
360 *cred = new_cred;
361
362 return SVN_NO_ERROR;
363 }
364
SvnContext(const std::string & config_dir_str)365 SvnContext::SvnContext( const std::string &config_dir_str )
366 : m_pool( NULL )
367 , m_context( NULL )
368 , m_config_dir( NULL )
369 {
370 memset( &m_context, 0, sizeof( m_context ) );
371
372 apr_pool_create( &m_pool, NULL );
373
374 #if defined( PYSVN_HAS_CLIENT_CREATE_CONTEXT2 )
375 svn_client_create_context2( &m_context, NULL, m_pool );
376 #else
377 svn_client_create_context( &m_context, m_pool );
378 #endif
379
380 if( !config_dir_str.empty() )
381 {
382 m_config_dir = svn_dirent_canonicalize( config_dir_str.c_str(), m_pool );
383 }
384
385 svn_config_ensure( m_config_dir, m_pool );
386
387 // get the config based on the config dir passed in
388 svn_config_get_config( &m_context->config, m_config_dir, m_pool );
389
390 svn_auth_provider_object_t *provider = NULL;
391 apr_array_header_t *providers = apr_array_make( m_pool, 11, sizeof( svn_auth_provider_object_t * ) );
392
393 #if defined( PYSVN_HAS_SVN_AUTH_PROVIDERS )
394
395 // simple providers
396 # if defined( PYSVN_HAS_SVN_AUTH_GET_PLATFORM_SPECIFIC_CLIENT_PROVIDERS )
397 svn_config_t *cfg = (svn_config_t *)apr_hash_get
398 (
399 m_context->config,
400 SVN_CONFIG_CATEGORY_CONFIG,
401 APR_HASH_KEY_STRING
402 );
403 svn_auth_get_platform_specific_client_providers( &providers, cfg, m_pool );
404
405 # else
406 # if defined( WIN32 )
407 svn_auth_get_windows_simple_provider(&provider, m_pool);
408 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
409 # endif
410 # if defined( DARWIN )
411 svn_auth_get_keychain_simple_provider(&provider, m_pool);
412 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
413 # endif
414 # endif
415
416 # if defined( PYSVN_HAS_AUTH_GET_SIMPLE_PROVIDER2 )
417 svn_auth_get_simple_provider2( &provider, NULL, NULL, m_pool );
418 # else
419 svn_auth_get_simple_provider( &provider, m_pool );
420 # endif
421 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
422
423 svn_auth_get_username_provider( &provider, m_pool );
424 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
425
426 svn_auth_get_simple_prompt_provider( &provider, handlerSimplePrompt, this, 1000000, m_pool );
427 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
428
429 // ssl providers
430
431 // order is important - file first then prompt providers
432 svn_auth_get_ssl_server_trust_file_provider( &provider, m_pool );
433 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
434
435 svn_auth_get_ssl_client_cert_file_provider( &provider, m_pool );
436 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
437
438 # if defined( PYSVN_HAS_AUTH_GET_SSL_CLIENT_CERT_PW_FILE_PROVIDER2 )
439 svn_auth_get_ssl_client_cert_pw_file_provider2( &provider, NULL, NULL, m_pool );
440 # else
441 svn_auth_get_ssl_client_cert_pw_file_provider( &provider, m_pool );
442 # endif
443 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
444
445 svn_auth_get_ssl_server_trust_prompt_provider( &provider, handlerSslServerTrustPrompt, this, m_pool );
446 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
447
448 svn_auth_get_ssl_client_cert_prompt_provider( &provider, handlerSslClientCertPrompt, this, 3, m_pool );
449 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
450
451 svn_auth_get_ssl_client_cert_pw_prompt_provider( &provider, handlerSslClientCertPwPrompt, this, 3, m_pool );
452 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
453 #else
454 // Pre 1.4.0 version
455 apr_array_header_t *providers = apr_array_make( m_pool, 8, sizeof( svn_auth_provider_object_t * ) );
456
457 // simple providers
458 svn_auth_provider_object_t *provider = NULL;
459 svn_client_get_simple_provider( &provider, m_pool );
460 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
461
462 svn_client_get_username_provider( &provider, m_pool );
463 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
464
465 svn_client_get_simple_prompt_provider( &provider, handlerSimplePrompt, this, 3, m_pool );
466 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
467
468 // ssl providers
469
470 // order is important - file first then prompt providers
471 svn_client_get_ssl_server_trust_file_provider( &provider, m_pool );
472 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
473
474 svn_client_get_ssl_client_cert_file_provider( &provider, m_pool );
475 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
476
477 svn_client_get_ssl_client_cert_pw_file_provider( &provider, m_pool );
478 *(svn_auth_provider_object_t **)apr_array_push( providers ) = provider;
479
480 svn_client_get_ssl_server_trust_prompt_provider( &provider, handlerSslServerTrustPrompt, this, m_pool );
481 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
482
483 svn_client_get_ssl_client_cert_prompt_provider( &provider, handlerSslClientCertPrompt, this, 3, m_pool );
484 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
485
486 svn_client_get_ssl_client_cert_pw_prompt_provider( &provider, handlerSslClientCertPwPrompt, this, 3, m_pool );
487 *(svn_auth_provider_object_t **)apr_array_push (providers) = provider;
488 #endif
489
490 svn_auth_baton_t *auth_baton = NULL;
491 svn_auth_open( &auth_baton, providers, m_pool );
492
493 // tell the auth functions where the config dir is
494 svn_auth_set_parameter( auth_baton, SVN_AUTH_PARAM_CONFIG_DIR, m_config_dir );
495
496 m_context->auth_baton = auth_baton;
497
498 #if defined( PYSVN_HAS_CONTEXT_LOG_MSG2 )
499 m_context->log_msg_func2 = handlerLogMsg2;
500 m_context->log_msg_baton2 = this;
501 #else
502 m_context->log_msg_func = handlerLogMsg;
503 m_context->log_msg_baton = this;
504 #endif
505 }
506
installCancel(bool install)507 void SvnContext::installCancel( bool install )
508 {
509 if( install )
510 {
511 m_context->cancel_func = handlerCancel;
512 m_context->cancel_baton = this;
513 }
514 else
515 {
516 m_context->cancel_func = NULL;
517 m_context->cancel_baton = NULL;
518 }
519 }
520
installNotify(bool install)521 void SvnContext::installNotify( bool install )
522 {
523 if( install )
524 {
525 #if defined( PYSVN_HAS_CONTEXT_NOTIFY2 )
526 m_context->notify_func2 = handlerNotify2;
527 m_context->notify_baton2 = this;
528 #else
529 m_context->notify_func = handlerNotify;
530 m_context->notify_baton = this;
531 #endif
532 }
533 else
534 {
535 #if defined( PYSVN_HAS_CONTEXT_NOTIFY2 )
536 m_context->notify_func2 = NULL;
537 m_context->notify_baton2 = NULL;
538 #else
539 m_context->notify_func = NULL;
540 m_context->notify_baton = NULL;
541 #endif
542 }
543 }
544
545 #if defined( PYSVN_HAS_CONTEXT_PROGRESS )
installProgress(bool install)546 void SvnContext::installProgress( bool install )
547 {
548 if( install )
549 {
550 m_context->progress_func = handlerProgress;
551 m_context->progress_baton = this;
552 }
553 else
554 {
555 m_context->progress_func = handlerProgress;
556 m_context->progress_baton = this;
557 }
558 }
559 #endif
560
561 #if defined( PYSVN_HAS_SVN_CLIENT_CTX_T__CONFLICT_FUNC )
installConflictResolver(bool install)562 void SvnContext::installConflictResolver( bool install )
563 {
564 if( install )
565 {
566 m_context->conflict_func = handlerConflictResolver;
567 m_context->conflict_baton = this;
568 }
569 else
570 {
571 m_context->conflict_func = NULL;
572 m_context->conflict_baton = NULL;
573 }
574 }
575 #endif
576
~SvnContext()577 SvnContext::~SvnContext()
578 {
579 if( m_pool )
580 {
581 apr_pool_destroy( m_pool );
582 }
583 }
584
operator svn_client_ctx_t*()585 SvnContext::operator svn_client_ctx_t *()
586 {
587 return m_context;
588 }
589
ctx()590 svn_client_ctx_t *SvnContext::ctx()
591 {
592 return m_context;
593 }
594
595 // only use this pool for data that has a life time
596 // that matches the life time of the context
getContextPool()597 apr_pool_t *SvnContext::getContextPool()
598 {
599 return m_pool;
600 }
601
602 //--------------------------------------------------------------------------------
603 //
604 // SvnTransaction
605 //
606 //--------------------------------------------------------------------------------
SvnTransaction()607 SvnTransaction::SvnTransaction()
608 : m_pool( NULL )
609 , m_repos( NULL )
610 , m_fs( NULL )
611 , m_txn( NULL )
612 , m_txn_name( NULL )
613 , m_rev_id( SVN_INVALID_REVNUM )
614 {
615 apr_pool_create( &m_pool, NULL );
616 }
617
init(const std::string & repos_path,const std::string & transaction_name,bool is_revision)618 svn_error_t *SvnTransaction::init( const std::string &repos_path,
619 const std::string &transaction_name, bool is_revision )
620 {
621 svn_error_t *error;
622
623 SvnPool scratch_pool( *this );
624
625 #if defined( PYSVN_HAS_REPOS_OPEN3 )
626 error = svn_repos_open3( &m_repos, repos_path.c_str(), NULL, m_pool, scratch_pool );
627
628 # elif defined( PYSNV_HAS_REPOS_OPEN2 )
629 error = svn_repos_open2( &m_repos, repos_path.c_str(), NULL, m_pool );
630
631 #else
632 error = svn_repos_open( &m_repos, repos_path.c_str(), m_pool );
633 #endif
634 if( error != NULL )
635 return error;
636
637 m_fs = svn_repos_fs( m_repos );
638 // what is a warning function?
639 // svn_fs_set_warning_func (m_fs, warning_func, NULL);
640
641 if( is_revision )
642 {
643 Py::String rev_name( transaction_name );
644 Py::Long long_val( rev_name );
645 m_rev_id = (long)long_val;
646 if (! SVN_IS_VALID_REVNUM( m_rev_id ))
647 return svn_error_create( SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
648 "invalid revision number supplied" );
649 }
650 else
651 {
652 m_txn_name = apr_pstrdup( m_pool, transaction_name.c_str() );
653 error = svn_fs_open_txn( &m_txn, m_fs, m_txn_name, m_pool );
654 }
655
656 return error;
657 }
658
~SvnTransaction()659 SvnTransaction::~SvnTransaction()
660 {
661 }
662
root(svn_fs_root_t ** root,apr_pool_t * pool)663 svn_error_t *SvnTransaction::root( svn_fs_root_t **root, apr_pool_t *pool )
664 {
665 if( is_revision() )
666 return svn_fs_revision_root( root, m_fs, m_rev_id, pool );
667 else
668 return svn_fs_txn_root( root, m_txn, pool );
669 }
670
operator svn_fs_txn_t*()671 SvnTransaction::operator svn_fs_txn_t *()
672 {
673 return m_txn;
674 }
675
operator svn_fs_t*()676 SvnTransaction::operator svn_fs_t *()
677 {
678 return m_fs;
679 }
680
operator svn_repos_t*()681 SvnTransaction::operator svn_repos_t *()
682 {
683 return m_repos;
684 }
685
686
transaction()687 svn_fs_txn_t *SvnTransaction::transaction()
688 {
689 return m_txn;
690 }
691
revision()692 svn_revnum_t SvnTransaction::revision()
693 {
694 return m_rev_id;
695 }
696
697 //--------------------------------------------------------------------------------
698 //
699 // Pool
700 //
701 //--------------------------------------------------------------------------------
SvnPool(SvnContext & ctx)702 SvnPool::SvnPool( SvnContext &ctx )
703 : m_pool( NULL )
704 {
705 m_pool = svn_pool_create( NULL );
706 }
707
SvnPool(SvnTransaction & txn)708 SvnPool::SvnPool( SvnTransaction &txn )
709 : m_pool( NULL )
710 {
711 m_pool = svn_pool_create( NULL );
712 }
713
~SvnPool()714 SvnPool::~SvnPool()
715 {
716 if( m_pool != NULL )
717 {
718 svn_pool_destroy( m_pool );
719 }
720 }
721
operator apr_pool_t*() const722 SvnPool::operator apr_pool_t *() const
723 {
724 return m_pool;
725 }
726
727 #if 0
728 // keep around as it useful for debugging pysvn
729 static const char *toHex( unsigned int num )
730 {
731 static char buffer[9];
732 for( int i=0; i<8; i++ )
733 {
734 buffer[i] = "0123456789abcdef"[ (num >> (32-(i+1)*4)) & 0x0f ];
735 }
736 buffer[8] = '\0';
737 return buffer;
738 }
739 #endif
740