#
# add_file "piece_table.cc"
#
# add_file "piece_table.hh"
#
# patch "Makefile.am"
# from [5be2cc6ac5a6b7390dcdc09b06389abecc45f495]
# to [21ab3c967663313d2a185edaf9cb37633658b911]
#
# patch "cvs_sync.cc"
# from [7cc1fd6ad5f679b89927f8c87f18f32de7bc6abe]
# to [a8c9f9c9b16162f891803e3b692f8784727c4975]
#
# patch "piece_table.cc"
# from []
# to [53950e7fe2e4a2cf12bcecd3e75280ed36209c94]
#
# patch "piece_table.hh"
# from []
# to [beb63ff93407222a2e23a24d16780b02dd267dba]
#
========================================================================
--- Makefile.am 5be2cc6ac5a6b7390dcdc09b06389abecc45f495
+++ Makefile.am 21ab3c967663313d2a185edaf9cb37633658b911
@@ -44,7 +44,7 @@
globish.cc globish.hh \
string_queue.cc string_queue.hh \
paths.cc paths.hh \
- \
+ piece_table.cc netxx_pipe.cc \
cleanup.hh unit_tests.hh interner.hh \
cycle_detector.hh randomfile.hh adler32.hh quick_alloc.hh \
netio.hh smap.hh gettext.h \
========================================================================
--- cvs_sync.cc 7cc1fd6ad5f679b89927f8c87f18f32de7bc6abe
+++ cvs_sync.cc a8c9f9c9b16162f891803e3b692f8784727c4975
@@ -1022,7 +1022,7 @@
{
// early short-circuit to avoid failure after lots of work
rsa_keypair_id key;
- N(guess_default_key(key,app), F("could not guess default signing key"));
+ get_user_key(key, app);
// Require the password early on, so that we don't do lots of work
// and then die.
app.signing_key = key;
========================================================================
--- piece_table.cc
+++ piece_table.cc 53950e7fe2e4a2cf12bcecd3e75280ed36209c94
@@ -0,0 +1,136 @@
+// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// copyright (C) 2002, 2003, 2004 graydon hoare
+// copyright (C) 2005 christof petig
+// all rights reserved.
+// licensed to the public under the terms of the GNU GPL (>= 2)
+// see the file COPYING for details
+
+#include "piece_table.hh"
+#include "sanity.hh"
+
+using namespace std;
+
+struct
+piece::piece_store
+{
+ std::vector< std::string > texts;
+ void index_deltatext(std::string const & dt,
+ std::vector & pieces);
+ void build_string(std::vector const & pieces,
+ std::string & out);
+ void reset() { texts.clear(); }
+};
+
+piece::piece_store piece::global_pieces;
+
+string
+piece::operator*() const
+{
+ return string(global_pieces.texts.at(string_id).data() + pos, len);
+}
+
+void
+piece::piece_store::build_string(piece_table const & pieces,
+ string & out)
+{
+ out.clear();
+ out.reserve(pieces.size() * 60);
+ for(piece_table::const_iterator i = pieces.begin();
+ i != pieces.end(); ++i)
+ out.append(texts.at(i->string_id), i->pos, i->len);
+}
+
+void
+piece::piece_store::index_deltatext(std::string const & dt,
+ piece_table & pieces)
+{
+ pieces.clear();
+ pieces.reserve(dt.size() / 30);
+ texts.push_back(dt);
+ unsigned long id = texts.size() - 1;
+ string::size_type begin = 0;
+ string::size_type end = dt.find('\n');
+ while(end != string::npos)
+ {
+ // nb: the piece includes the '\n'
+ pieces.push_back(piece(begin, (end - begin) + 1, id));
+ begin = end + 1;
+ end = dt.find('\n', begin);
+ }
+ if (begin != dt.size())
+ {
+ // the text didn't end with '\n', so neither does the piece
+ end = dt.size();
+ pieces.push_back(piece(begin, end - begin, id));
+ }
+}
+
+
+static void
+process_one_hunk(piece::piece_table const & source,
+ piece::piece_table & dest,
+ piece::piece_table::const_iterator & i,
+ int & cursor)
+{
+ string directive = **i;
+ assert(directive.size() > 1);
+ ++i;
+
+ try
+ {
+ char code;
+ int pos, len;
+ if (sscanf(directive.c_str(), " %c %d %d", &code, &pos, &len) != 3)
+ throw oops("illformed directive '" + directive + "'");
+
+ if (code == 'a')
+ {
+ // 'ax y' means "copy from source to dest until cursor == x, then
+ // copy y lines from delta, leaving cursor where it is"
+ while (cursor < pos)
+ dest.push_back(source.at(cursor++));
+ I(cursor == pos);
+ while (len--)
+ dest.push_back(*i++);
+ }
+ else if (code == 'd')
+ {
+ // 'dx y' means "copy from source to dest until cursor == x-1,
+ // then increment cursor by y, ignoring those y lines"
+ while (cursor < (pos - 1))
+ dest.push_back(source.at(cursor++));
+ I(cursor == pos - 1);
+ cursor += len;
+ }
+ else
+ throw oops("unknown directive '" + directive + "'");
+ }
+ catch (std::out_of_range & oor)
+ {
+ throw oops("std::out_of_range while processing " + directive
+ + " with source.size() == "
+ + boost::lexical_cast(source.size())
+ + " and cursor == "
+ + boost::lexical_cast(cursor));
+ }
+}
+
+void
+piece::apply_diff(piece_table const & source_lines,
+ piece_table & dest_lines,
+ std::string const & deltatext)
+{
+ dest_lines.clear();
+ dest_lines.reserve(source_lines.size());
+
+ piece_table deltalines;
+ global_pieces.index_deltatext(deltatext, deltalines);
+
+ int cursor = 0;
+ for (piece_table::const_iterator i = deltalines.begin();
+ i != deltalines.end(); )
+ process_one_hunk(source_lines, dest_lines, i, cursor);
+ while (cursor < static_cast(source_lines.size()))
+ dest_lines.push_back(source_lines[cursor++]);
+}
+
========================================================================
--- piece_table.hh
+++ piece_table.hh beb63ff93407222a2e23a24d16780b02dd267dba
@@ -0,0 +1,36 @@
+// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// copyright (C) 2002, 2003, 2004 graydon hoare
+// copyright (C) 2005 christof petig
+// all rights reserved.
+// licensed to the public under the terms of the GNU GPL (>= 2)
+// see the file COPYING for details
+
+#include
+#include
+
+// piece table stuff
+
+struct
+piece
+{
+ piece(std::string::size_type p, std::string::size_type l, unsigned long id) :
+ pos(p), len(l), string_id(id) {}
+ std::string::size_type pos;
+ std::string::size_type len;
+ unsigned long string_id;
+ std::string operator*() const;
+
+ typedef std::vector piece_table;
+
+ struct piece_store;
+ static piece_store global_pieces;
+
+ static void index_deltatext(std::string const & dt, piece_table & pieces);
+ static void build_string(piece_table const & pieces, std::string & out);
+ static void apply_diff(piece_table const & source_lines,
+ piece_table & dest_lines,
+ std::string const & deltatext);
+
+ static void reset();
+};
+