func (cp *ConstantPool) readConstant(c *Constant, br *util.BinaryReader) error { if err := br.ReadInterface(&c.Tag); err != nil { return err } else { switch c.Tag { case CONSTANT_String: fallthrough case CONSTANT_MethodType: fallthrough case CONSTANT_Class: return br.ReadInterface(&c.Index[0]) case CONSTANT_Fieldref: fallthrough case CONSTANT_Methodref: fallthrough case CONSTANT_NameAndType: fallthrough case CONSTANT_InvokeDynamic: fallthrough case CONSTANT_InterfaceMethodref: if err := br.ReadInterface(&c.Index[0]); err != nil { return err } else { return br.ReadInterface(&c.Index[1]) } case CONSTANT_Integer: var v int32 return br.ReadInterface(&v) case CONSTANT_Float: var v float32 return br.ReadInterface(&v) case CONSTANT_Long: var v int64 return br.ReadInterface(&v) case CONSTANT_Double: var v float64 return br.ReadInterface(&v) case CONSTANT_Utf8: var length u2 if err := br.ReadInterface(&length); err != nil { return err } else if d, err := br.Read(int(length)); err != nil { return err } else { c.Value = string(d) } case CONSTANT_MethodHandle: var ref_kind u1 if err := br.ReadInterface(&ref_kind); err != nil { return err } else { c.Index[0] = u2(ref_kind) return br.ReadInterface(&c.Index[1]) } default: return errors.New(fmt.Sprintf("Unimplemented tag: %d", c.Tag)) } } return nil }
func (mh *MetadataHeader) MetadataUtil(br *util.BinaryReader) (*MetadataUtil, error) { var ( ret MetadataUtil ) off, err := br.Seek(0, 1) if err != nil { return nil, err } base := off for _, h := range mh.StreamHeaders { switch h.Name { case "#~": off += int64(h.Offset) case "#Strings": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.StringHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.StringHeap.Rows = h.Size case "#Blob": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.BlobHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.BlobHeap.Rows = h.Size case "#GUID": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.GuidHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.GuidHeap.Rows = h.Size } } if _, err := br.Seek(off, 0); err != nil { return nil, err } h := hash_tilde_stream_header{} if err := br.ReadInterface(&h); err != nil { return nil, err } if h.HeapSizes&bit_stringHeapIndexSize != 0 { ret.StringHeap.RowSize = 4 } else { ret.StringHeap.RowSize = 2 } if h.HeapSizes&bit_blobHeapIndexSize != 0 { ret.BlobHeap.RowSize = 4 } else { ret.BlobHeap.RowSize = 2 } if h.HeapSizes&bit_guidHeapIndexSize != 0 { ret.GuidHeap.RowSize = 4 } else { ret.GuidHeap.RowSize = 2 } for i := range ret.Tables { if valid := (h.Valid >> uint(i)) & 1; valid != 0 { if ret.Tables[i].Rows, err = br.Uint32(); err != nil { return nil, err } ret.Tables[i].RowType = table_row_type_lut[i] } } for i := range ret.Tables { if ret.Tables[i].Rows != 0 { if size, err := ret.Size(ret.Tables[i].RowType); err != nil { return nil, err } else { ret.Tables[i].RowSize = uint32(size) if ret.Tables[i].data, err = br.Read(int(ret.Tables[i].RowSize * ret.Tables[i].Rows)); err != nil { return nil, err } } } } return &ret, nil }