Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add some more U::Buffer methods

  • Loading branch information...
commit cb83c292c6a1995248c598cb7048c913c131b940 1 parent a425794
Nikolai Weibull authored
View
116 ext/u/rb_u_buffer.c
@@ -274,37 +274,36 @@ rb_u_buffer_append_m(int argc, VALUE *argv, VALUE self)
return self;
}
-/* @overload ==(other)
- * @param [U::Buffer] other
- * @return [Boolean] True if the receiver’s class and content equal those of
- * OTHER */
+/* @return [U::String] A UTF-8-encoded string of the receiver’s content */
VALUE
-rb_u_buffer_eql(VALUE self, VALUE rbother)
+rb_u_buffer_to_u(VALUE self)
{
- if (self == rbother)
- return Qtrue;
-
- if (!RTEST(rb_obj_is_kind_of(rbother, rb_cUBuffer)))
- return Qfalse;
-
const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
- const struct rb_u_buffer *other = RVAL2RBUBUFFER(rbother);
- return buffer->length == other->length &&
- memcmp(buffer->c, other->c, other->length) == 0 ?
- Qtrue : Qfalse;
+ return rb_u_string_new_c(self, buffer->c, buffer->length);
}
-/* @return [Fixnum] The hash value of the receiver’s content */
+/* @return [U::String] The UTF-8-encoded string of the receiver’s content after
+ * clearing it from the receiver
+ * @note This method differs from {#to_u} in that it doesn’t copy the result,
+ * so it’s generally faster; call it when you’re done building your
+ * {U::String}. */
VALUE
-rb_u_buffer_hash(VALUE self)
+rb_u_buffer_to_u_bang(VALUE self)
{
- const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
- return INT2FIX(rb_memhash(buffer->c, buffer->length));
+ char *c = buffer->c;
+ long length = buffer->length;
+ rb_u_buffer_reset(buffer);
+
+ REALLOC_N(c, char, length + 1);
+ c[length] = '\0';
+
+ return rb_u_string_new_c_own(self, c, length);
}
-/* @return [String] A UTF-8 encoded string of the receiver’s content */
+/* @return [String] A UTF-8-encoded string of the receiver’s content */
VALUE
rb_u_buffer_to_s(VALUE self)
{
@@ -315,33 +314,68 @@ rb_u_buffer_to_s(VALUE self)
return result;
}
-/* @return [U::String] A UTF-8 encoded string of the receiver’s content */
+/* @return [Integer] The number of characters in the receiver */
VALUE
-rb_u_buffer_to_u(VALUE self)
+rb_u_buffer_length(VALUE self)
{
const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ return UINT2NUM(u_n_chars_n(buffer->c, buffer->length));
+}
- return rb_u_string_new_c(self, buffer->c, buffer->length);
+/* @return [Integer] The number of bytes required to represent the receiver */
+VALUE
+rb_u_buffer_bytesize(VALUE self)
+{
+ const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ return UINT2NUM(buffer->length);
}
-/* @return [U::String] The UTF-8 encoded string of the receiver’s content after
- * clearing it from the receiver
- * @note This method differs from {#to_u} in that it doesn’t copy the result,
- * so it’s generally faster; call it when you’re done building your
- * {U::String}. */
+/* Returns the width of the receiver. The width is defined as the sum of the
+ * number of “cells” on a terminal or similar cell-based display that the
+ * characters in the string will require.
+ *
+ * Characters that are {U::String#wide?} have a width of 2. Characters that
+ * are {U::String#zero_width?} have a width of 0. Other characters have a
+ * width of 1.
+ *
+ * @return [Integer]
+ * @see http://www.unicode.org/reports/tr11/
+ * Unicode Standard Annex #11: East Asian Width */
VALUE
-rb_u_buffer_to_u_bang(VALUE self)
+rb_u_buffer_width(VALUE self)
{
- struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ return UINT2NUM(u_width_n(buffer->c, buffer->length));
+}
- char *c = buffer->c;
- long length = buffer->length;
- rb_u_buffer_reset(buffer);
+/* @overload ==(other)
+ * @param [U::Buffer] other
+ * @return [Boolean] True if the receiver’s class and content equal those of
+ * OTHER */
+VALUE
+rb_u_buffer_eql(VALUE self, VALUE rbother)
+{
+ if (self == rbother)
+ return Qtrue;
- REALLOC_N(c, char, length + 1);
- c[length] = '\0';
+ if (!RTEST(rb_obj_is_kind_of(rbother, rb_cUBuffer)))
+ return Qfalse;
- return rb_u_string_new_c_own(self, c, length);
+ const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+ const struct rb_u_buffer *other = RVAL2RBUBUFFER(rbother);
+
+ return buffer->length == other->length &&
+ memcmp(buffer->c, other->c, other->length) == 0 ?
+ Qtrue : Qfalse;
+}
+
+/* @return [Fixnum] The hash value of the receiver’s content */
+VALUE
+rb_u_buffer_hash(VALUE self)
+{
+ const struct rb_u_buffer *buffer = RVAL2RBUBUFFER(self);
+
+ return INT2FIX(rb_memhash(buffer->c, buffer->length));
}
/* Document-class: U::Buffer
@@ -355,12 +389,20 @@ Init_u_buffer(VALUE mU)
rb_define_alloc_func(rb_cUBuffer, rb_u_buffer_alloc);
rb_define_private_method(rb_cUBuffer, "initialize", rb_u_buffer_initialize, -1);
rb_define_private_method(rb_cUBuffer, "initialize_copy", rb_u_buffer_initialize_copy, 1);
+
rb_define_method(rb_cUBuffer, "append", rb_u_buffer_append_m, -1);
rb_define_alias(rb_cUBuffer, "<<", "append");
rb_define_method(rb_cUBuffer, "append_format", rb_u_buffer_append_format_m, -1); /* in ext/u/rb_u_string_format.c */
- rb_define_method(rb_cUBuffer, "to_s", rb_u_buffer_to_s, 0);
+
rb_define_method(rb_cUBuffer, "to_u", rb_u_buffer_to_u, 0);
rb_define_method(rb_cUBuffer, "to_u!", rb_u_buffer_to_u_bang, 0);
+ rb_define_method(rb_cUBuffer, "to_s", rb_u_buffer_to_s, 0);
+
+ rb_define_method(rb_cUBuffer, "length", rb_u_buffer_length, 0);
+ rb_define_alias(rb_cUBuffer, "size", "length");
+ rb_define_method(rb_cUBuffer, "bytesize", rb_u_buffer_bytesize, 0);
+ rb_define_method(rb_cUBuffer, "width", rb_u_buffer_width, 0);
+
rb_define_method(rb_cUBuffer, "==", rb_u_buffer_eql, 1);
rb_define_alias(rb_cUBuffer, "eql?", "==");
rb_define_method(rb_cUBuffer, "hash", rb_u_buffer_hash, 0);
View
4 ext/u/rb_u_buffer.h
@@ -11,10 +11,14 @@ VALUE rb_u_buffer_append_char(VALUE self, uint32_t c);
VALUE rb_u_buffer_append_char_n(VALUE self, uint32_t c, long n);
VALUE rb_u_buffer_append_m(int argc, VALUE *argv, VALUE self);
+VALUE rb_u_buffer_bytesize(VALUE self);
VALUE rb_u_buffer_eql(VALUE self, VALUE rbother);
VALUE rb_u_buffer_hash(VALUE self);
+VALUE rb_u_buffer_inspect(VALUE self);
+VALUE rb_u_buffer_length(VALUE self);
VALUE rb_u_buffer_to_s(VALUE self);
VALUE rb_u_buffer_to_u(VALUE self);
VALUE rb_u_buffer_to_u_bang(VALUE self);
+VALUE rb_u_buffer_width(VALUE self);
void Init_u_buffer(VALUE mU);
View
4 ext/u/rb_u_string_width.c
@@ -9,9 +9,7 @@
*
* @return [Integer]
* @see http://www.unicode.org/reports/tr11/
- * Unicode Standard Annex #11: East Asian Width
- * @see #wide?
- * @see #wide_cjk? */
+ * Unicode Standard Annex #11: East Asian Width */
VALUE
rb_u_string_width(VALUE self)
{
View
5 test/unit/u/buffer.rb
@@ -24,6 +24,11 @@
expect '#<U::Buffer äbcdëfwvxÿz>' do U::Buffer.new.append('äbcdëfwvxÿz'.u).inspect end
expect '#<U::Buffer äbcdë…wvxÿz>' do U::Buffer.new.append('äbcdëfgwvxÿz'.u).inspect end
+ expect 3 do U::Buffer.new.append('äbc'.u).length end
+ expect 3 do U::Buffer.new.append('äbc'.u).size end
+ expect 4 do U::Buffer.new.append('äbc'.u).bytesize end
+ expect 4 do U::Buffer.new.append('あbc'.u).width end
+
expect result.tainted? do U::Buffer.new.taint.to_s end
expect result.tainted? do U::Buffer.new.taint.to_u end
end
Please sign in to comment.
Something went wrong with that request. Please try again.