/*
* ====================================================================
* Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved.
*
* This software is licensed as described in the file LICENSE.txt,
* which you should have received as part of this distribution.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://rapidsvn.tigris.org/.
* ====================================================================
*/
#if defined( _MSC_VER) && _MSC_VER <= 1200
#pragma warning( disable: 4786 )// debug symbol truncated
#endif
// Subversion api
#include <apr_xlate.h>
#include <svn_dirent_uri.h>
#include "svn_client.h"
// subcpp
#include "client.hpp"
#include "exception.hpp"
#include "pool.hpp"
#include "diff_summary.hpp"
namespace svn
{
struct DiffHelper
{
apr_file_t* m_outfile;
apr_file_t* m_errfile;
Pool m_pool;
DiffHelper()
:
m_outfile( NULL ),
m_errfile( NULL )
{
ErrorChecker throwOnFail;
// svn_client_diff needs a temporary file to write diff output to
throwOnFail << svn_io_open_unique_file3( &m_outfile, NULL, NULL, svn_io_file_del_on_pool_cleanup, m_pool, m_pool );
// and another one to write errors to
throwOnFail << svn_io_open_unique_file3( &m_errfile, NULL, NULL, svn_io_file_del_on_pool_cleanup, m_pool, m_pool );
}
std::string GetDiffString()
{
ErrorChecker throwOnFail;
apr_off_t offset = 0;
// read entire error file
throwOnFail << svn_io_file_seek( m_errfile, APR_SET, &offset, m_pool );
svn_stringbuf_t* errorString = 0;
throwOnFail << svn_stringbuf_from_aprfile( &errorString, m_errfile, m_pool );
svn_io_file_close( m_errfile, m_pool );
if ( errorString->len != 0 )
{
throw Exception( errorString->data );
}
// read entire diff file
throwOnFail << svn_io_file_seek( m_outfile, APR_SET, &offset, m_pool );
svn_stringbuf_t* diffString = 0;
throwOnFail << svn_stringbuf_from_aprfile( &diffString, m_outfile, m_pool );
svn_io_file_close( m_outfile, m_pool );
return std::string( diffString->data, diffString->len );
}
};
std::string Client::Diff( const Path& path1,
const Path& path2,
const Revision& revision1,
const Revision& revision2,
svn_depth_t depth,
bool ignoreAncestry,
bool noDiffDeleted,
bool ignoreContentType )
{
DiffHelper helper;
ErrorChecker throwOnFail;
// run diff
throwOnFail << svn_client_diff4
(
NULL,
path1.c_str(),
revision1.revision(),
path2.c_str(),
revision2.revision(),
NULL, /* TODO: Relative to dir */
depth,
ignoreAncestry,
noDiffDeleted,
ignoreContentType,
APR_LOCALE_CHARSET, /* TODO: Support more character encodings */
helper.m_outfile,
helper.m_errfile,
NULL, /* TODO: Support Changelists */
*m_context,
helper.m_pool
);
return helper.GetDiffString();
}
std::string Client::Diff( const Path& path,
const Revision& startRevision,
const Revision& endRevision,
const Revision& pegRevision,
svn_depth_t depth,
bool ignoreAncestry,
bool noDiffDeleted,
bool ignoreContentType )
{
DiffHelper helper;
ErrorChecker throwOnFail;
// run diff
throwOnFail << svn_client_diff_peg4
(
NULL,
path.c_str(),
pegRevision.revision(),
startRevision.revision(),
endRevision.revision(),
NULL, /* TODO: Relative to dir */
depth,
ignoreAncestry,
noDiffDeleted,
ignoreContentType,
APR_LOCALE_CHARSET, /* TODO: Support more character encodings */
helper.m_outfile,
helper.m_errfile,
NULL, /* TODO: Support Changelists */
*m_context,
helper.m_pool
);
return helper.GetDiffString();
}
struct DiffSummaryCollector
{
std::vector< DiffSummary > m_summary;
bool operator()( const svn_client_diff_summarize_t& diff )
{
m_summary.push_back( DiffSummary( diff ) );
return true;
}
};
std::vector< DiffSummary > Client::DiffSummarize( const Path& path,
const Revision& startRevision,
const Revision& endRevision,
const Revision& pegRevision,
svn_depth_t depth,
bool ignoreAncestry )
{
DiffSummaryCollector collector;
DiffSummarizeCallback( path, startRevision, endRevision, collector, pegRevision, depth, ignoreAncestry );
return collector.m_summary;
}
std::vector< DiffSummary > Client::DiffSummarize( const Path& path1,
const Path& path2,
const svn::Revision& revision1,
const svn::Revision& revision2,
svn_depth_t depth,
bool ignoreAncestry )
{
DiffSummaryCollector collector;
DiffSummarizeCallback( path1, path2, collector, revision1, revision2, depth, ignoreAncestry );
return collector.m_summary;
}
}