Ejemplo n.º 1
0
	void cut(string_ptr& into, size_t i, size_t l) const {
		/*get the start*/
		BYTE const* nstart = start;
		repeat(i) utf8_adv(nstart);
		/*for the trivial case where we would reach
		the end of this string, don't bother
		iterating over the rest of the string
		*/
		if(i + l == len) {
			into.reset(
				new Utf8Impl(buffer, nstart, end, l)
			);
			return;
		}
		/*iterate over the substring.  since we are
		iterating over the substring anyway, we might
		as well check if the substring is pure ascii.
		*/
		bool nonascii = false;
		BYTE const* nend = nstart;
		repeat(l) utf8_adv_check(nend, nonascii);
		if(nonascii) {
			into.reset(
				new Utf8Impl(buffer, nstart, nend, l)
			);
			return;
		} else {
			into.reset(
				new AsciiImpl(buffer, nstart, l)
			);
			return;
		}
	}
Ejemplo n.º 2
0
void RopeImpl::append_string_impl(
		string_ptr& dest,
		string_ptr const& one,
		string_ptr const& two) {
	/*trivial cases where one string is empty*/
	if(one->length() == 0) {
		dest = two;
		return;
	} else if(two->length() == 0){
		dest = one;
		return;
	}
	/*check for catting two short Ascii strings.*/
	AsciiImpl* as1 = dynamic_cast<AsciiImpl*>(one.get());
	if(as1 && as1->length() < (ASCII_BUFFER_LEVEL / 2)) {
		AsciiImpl* as2 = dynamic_cast<AsciiImpl*>(two.get());
		if(as2 && as2->length() < (ASCII_BUFFER_LEVEL / 2)) {
			size_t l1 = as1->length();
			size_t l2 = as2->length();
			/*create a single buffer and concat them*/
			boost::shared_array<BYTE> nbp(new BYTE(l1 + l2));
			std::copy(as2->start, &as2->start[l2],
				std::copy(as1->start, &as1->start[l1],
					&nbp[0]
				)
			);
			dest.reset(new AsciiImpl(nbp, &nbp[0], l1 + l2));
			return;
		}
	}
	size_t d1 = one->rope_depth();
	size_t d2 = two->rope_depth();
	if(d1 > d2 + 1) {
		/*first subtree is pretty heavy, check if:
		  one    two
		   /\     |
		  /\ c    d
		 a  b
		If so, do this:
		    /\
		   /  \
		  /\  /\
		 a b  c d
		*/
		RopeImpl& r1 = static_cast<RopeImpl&>(*one);
		size_t d1_2 = r1.two->rope_depth();
		if(d1_2 <= d2 + 1) {
			string_ptr tmp;
			base_append_string_impl(tmp, r1.two, two, d1_2, d2);
			append_string_impl(dest, r1.one, tmp);
			return;
		}
	}
	base_append_string_impl(dest, one, two, d1, d2);
}
Ejemplo n.º 3
0
void RopeImpl::base_append_string_impl(
		string_ptr& dest,
		string_ptr const& one,
		string_ptr const& two,
		size_t d1,
		size_t d2) {
	size_t nd =
		d1 > d2 ?		d1 + 1 :
		/*otherwise*/		d2 + 1 ;
	dest.reset(
		new RopeImpl(one, two, nd, one->length())
	);
}
Ejemplo n.º 4
0
	void cut(string_ptr& into, size_t i, size_t l) const {
		into.reset(
			new AsciiImpl(buffer, start + i, l)
		);
	}