+static int
+for_each_prop (VALUE tag, VALUE arg, VALUE stream)
+{
+ VALUE value, type, chunks;
+ long len, i;
+
+ if (rb_obj_is_kind_of (arg, rb_cArray) == Qfalse)
+ rb_raise (ePropError, "hash value is not an array");
+
+ value = rb_ary_entry (arg, 0);
+ if (NIL_P (value))
+ return ST_CONTINUE;
+
+ type = rb_ary_entry (arg, 1);
+ chunks = rb_funcall (value, id_to_eet_chunks, 2, tag, type);
+
+ len = RARRAY (chunks)->len;
+
+ for (i = 0; i < len; i++)
+ rb_funcall (stream, id_push, 1, rb_ary_entry (chunks, i));
+
+ return ST_CONTINUE;
+}
+
+/*
+ * :call-seq:
+ * object.to_eet -> string
+ *
+ * Serializes the receiver to EET format.
+ */
+static VALUE
+c_to_eet (VALUE self)
+{
+ VALUE props, name, stream, chunk, args[2];
+
+ props = rb_funcall (self, id_to_eet_properties, 0);
+
+ if (rb_obj_is_kind_of (props, rb_cHash) == Qfalse ||
+ !RHASH (props)->tbl->num_entries)
+ rb_raise (ePropError, "invalid EET properties");
+
+ name = rb_funcall (self, id_to_eet_name, 0);
+ StringValue (name);
+
+ if (!RSTRING (name)->len ||
+ rb_funcall (name, id_include, 1, INT2FIX (0)))
+ rb_raise (eNameError, "invalid EET name");
+
+ stream = rb_class_new_instance (0, NULL, cStream);
+
+ rb_hash_foreach (props, for_each_prop, stream);
+
+ args[0] = name;
+ args[1] = rb_funcall (stream, id_serialize, 0);
+ chunk = rb_class_new_instance (2, args, cChunk);
+
+ stream = rb_class_new_instance (1, &chunk, cStream);
+
+ return rb_funcall (stream, id_serialize, 0);
+}
+