+}
+
+void
+_Jv_ClassReader::finish_reflection_data ()
+{
+ if (data_stream == NULL)
+ return;
+ data_stream->writeByte(JV_DONE_ATTR);
+ data_stream->flush();
+ int nbytes = reflection_data->count;
+ unsigned char *new_bytes = (unsigned char *) _Jv_AllocBytes (nbytes);
+ memcpy (new_bytes, elements (reflection_data->buf), nbytes);
+ def->reflection_data = new_bytes;
+}
+
+void
+_Jv_ClassReader::handleEnclosingMethod (int len)
+{
+ if (len != 4)
+ throw_class_format_error ("invalid EnclosingMethod attribute");
+ // FIXME: only allow one...
+
+ int class_index = read2u();
+ check_tag (class_index, JV_CONSTANT_Class);
+ prepare_pool_entry (class_index, JV_CONSTANT_Class);
+
+ int method_index = read2u();
+ // Zero is ok and means no enclosing method.
+ if (method_index != 0)
+ {
+ check_tag (method_index, JV_CONSTANT_NameAndType);
+ prepare_pool_entry (method_index, JV_CONSTANT_NameAndType);
+ }
+
+ ::java::io::DataOutputStream *stream = get_reflection_stream ();
+ stream->writeByte(JV_CLASS_ATTR);
+ stream->writeInt(5);
+ stream->writeByte(JV_ENCLOSING_METHOD_KIND);
+ stream->writeShort(class_index);
+ stream->writeShort(method_index);
+}
+
+void
+_Jv_ClassReader::handleGenericSignature (jv_attr_type type,
+ unsigned short index,
+ int len)
+{
+ if (len != 2)
+ throw_class_format_error ("invalid Signature attribute");
+
+ int cpool_idx = read2u();
+ check_tag (cpool_idx, JV_CONSTANT_Utf8);
+ prepare_pool_entry (cpool_idx, JV_CONSTANT_Utf8, false);
+
+ ::java::io::DataOutputStream *stream = get_reflection_stream ();
+ stream->writeByte(type);
+ int attrlen = 3;
+ if (type != JV_CLASS_ATTR)
+ attrlen += 2;
+ stream->writeInt(attrlen);
+ if (type != JV_CLASS_ATTR)
+ stream->writeShort(index);
+ stream->writeByte(JV_SIGNATURE_KIND);
+ stream->writeShort(cpool_idx);
+}
+
+void
+_Jv_ClassReader::handleAnnotationElement()
+{
+ int tag = read1u();
+ switch (tag)
+ {
+ case 'B':
+ case 'C':
+ case 'S':
+ case 'Z':
+ case 'I':
+ {
+ int index = read2u();
+ check_tag (index, JV_CONSTANT_Integer);
+ prepare_pool_entry (index, JV_CONSTANT_Integer);
+ }
+ break;
+ case 'D':
+ {
+ int index = read2u();
+ check_tag (index, JV_CONSTANT_Double);
+ prepare_pool_entry (index, JV_CONSTANT_Double);
+ }
+ break;
+ case 'F':
+ {
+ int index = read2u();
+ check_tag (index, JV_CONSTANT_Float);
+ prepare_pool_entry (index, JV_CONSTANT_Float);
+ }
+ break;
+ case 'J':
+ {
+ int index = read2u();
+ check_tag (index, JV_CONSTANT_Long);
+ prepare_pool_entry (index, JV_CONSTANT_Long);
+ }
+ break;
+ case 's':
+ {
+ int index = read2u();
+ // Despite what the JVM spec says, compilers generate a Utf8
+ // constant here, not a String.
+ check_tag (index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (index, JV_CONSTANT_Utf8, false);
+ }
+ break;
+
+ case 'e':
+ {
+ int type_name_index = read2u();
+ int const_name_index = read2u ();
+ check_tag (type_name_index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (type_name_index, JV_CONSTANT_Utf8);
+ check_tag (const_name_index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (const_name_index, JV_CONSTANT_Utf8, false);
+ }
+ break;
+ case 'c':
+ {
+ int index = read2u();
+ check_tag (index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (index, JV_CONSTANT_Utf8);
+ }
+ break;
+ case '@':
+ handleAnnotation();
+ break;
+ case '[':
+ {
+ int n_array_elts = read2u ();
+ for (int i = 0; i < n_array_elts; ++i)
+ handleAnnotationElement();
+ }
+ break;
+ default:
+ throw_class_format_error ("invalid annotation element");
+ }
+}
+
+void
+_Jv_ClassReader::handleAnnotation()
+{
+ int type_index = read2u();
+ check_tag (type_index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
+
+ int npairs = read2u();
+ for (int i = 0; i < npairs; ++i)
+ {
+ int name_index = read2u();
+ check_tag (name_index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
+ handleAnnotationElement();
+ }
+}