Skip to content

Commit

Permalink
added some new attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
phith0n committed Apr 4, 2024
1 parent eea28d9 commit 95e0399
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 32 deletions.
47 changes: 47 additions & 0 deletions class/annotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package class

Check failure on line 1 in class/annotation.go

View workflow job for this annotation

GitHub Actions / lint

: # github.com/phith0n/zkar/class [github.com/phith0n/zkar/class.test]

import (
"encoding/binary"
"fmt"
"github.com/phith0n/zkar/commons"
)

type Annotation struct {
TypeIndex uint16
ElementValuePairs []*ElementValuePair
}

type ElementValuePair struct {
ElementNameIndex uint16
ElementValue *ElementValue
}

func NewAnnotation(stream *commons.Stream) (*Annotation, error) {
bs, err := stream.ReadN(4)
if err != nil {
return nil, fmt.Errorf("read Annotation failed, no enough data in the stream")
}

a := &Annotation{
TypeIndex: binary.BigEndian.Uint16(bs[:2]),
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs[2:]); i++ {
bs, err = stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read Annotation ElementValuePair[%d] failed, no enough data in the stream", i)
}

pair := &ElementValuePair{
ElementNameIndex: binary.BigEndian.Uint16(bs),
}
pair.ElementValue, err = NewElementValue(stream)
if err != nil {
return nil, fmt.Errorf("read Annotation ElementValuePair[%d] failed, caused by: %v", i, err)
}

a.ElementValuePairs = append(a.ElementValuePairs, pair)
}

return a, nil
}
31 changes: 0 additions & 31 deletions class/attr_annotations.go

This file was deleted.

2 changes: 1 addition & 1 deletion class/attr_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (a *AttrRecord) readInfo(stream *commons.Stream) error {
func (a *AttrRecord) readComponent(stream *commons.Stream) (*RecordComponentInfo, error) {
bs, err := stream.ReadN(4)
if err != nil {
return nil, fmt.Errorf("read AttrRecord Component[%d] failed, no enough data in the stream", i)
return nil, fmt.Errorf("read AttrRecord Component failed, no enough data in the stream")
}

component := &RecordComponentInfo{
Expand Down
31 changes: 31 additions & 0 deletions class/attr_runtime_visible_annotations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package class

import (
"encoding/binary"
"fmt"
"github.com/phith0n/zkar/commons"
)

type AttrRuntimeVisibleAnnotations struct {
*AttributeBase

Annotations []*Annotation
}

func (a *AttrRuntimeVisibleAnnotations) readInfo(stream *commons.Stream) error {
bs, err := stream.ReadN(2)
if err != nil {
return fmt.Errorf("read AttrRuntimeVisibleAnnotations failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
annotation, err := NewAnnotation(stream)
if err != nil {
return fmt.Errorf("read AttrRuntimeVisibleAnnotations Annotation[%d] failed, no enough data in the stream", i)
}

a.Annotations = append(a.Annotations, annotation)
}

return nil
}
54 changes: 54 additions & 0 deletions class/attr_runtime_visible_parameter_annotations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package class

import (
"encoding/binary"
"fmt"
"github.com/phith0n/zkar/commons"
)

type AttrRuntimeVisibleParameterAnnotations struct {
*AttributeBase

Parameters []*ParameterAnnotation
}

type ParameterAnnotation struct {
Annotations []*Annotation
}

func (a *AttrRuntimeVisibleParameterAnnotations) readInfo(stream *commons.Stream) error {
bs, err := stream.ReadN(1)
if err != nil {
return fmt.Errorf("read Annotation failed, no enough data in the stream")
}

for i := uint8(0); i < bs[0]; i++ {
p, err := a.readParameter(stream)
if err != nil {
return err
}

a.Parameters = append(a.Parameters, p)
}

return nil
}

func (a *AttrRuntimeVisibleParameterAnnotations) readParameter(stream *commons.Stream) (*ParameterAnnotation, error) {
bs, err := stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read ParameterAnnotation failed, no enough data in the stream")
}

parameter := &ParameterAnnotation{}
for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
annotation, err := NewAnnotation(stream)
if err != nil {
return nil, fmt.Errorf("read ParameterAnnotation failed, caused by: %v", err)
}

parameter.Annotations = append(parameter.Annotations, annotation)
}

return parameter, nil
}
84 changes: 84 additions & 0 deletions class/element_value.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package class

import (
"encoding/binary"
"fmt"
"github.com/phith0n/zkar/commons"
)

// ElementValue https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms-4.7.16.1
type ElementValue struct {
Tag byte

ConstValueIndex uint16
EnumConstValue *EnumConstValue
ClassInfoIndex uint16
AnnotationValue *Annotation
ArrayValue []*ElementValue
}

type EnumConstValue struct {
TypeNameIndex uint16
ConstNameIndex uint16
}

func NewElementValue(stream *commons.Stream) (*ElementValue, error) {
bs, err := stream.ReadN(1)
if err != nil {
return nil, fmt.Errorf("read ElementValue tag failed, no enough data in the stream")
}

element := &ElementValue{
Tag: bs[0],
}

switch element.Tag {
case 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', 's':
bs, err = stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read ElementValue ConstValueIndex failed, no enough data in the stream")
}

element.ConstValueIndex = binary.BigEndian.Uint16(bs)
case 'e':
bs, err = stream.ReadN(4)
if err != nil {
return nil, fmt.Errorf("read ElementValue EnumConstValue failed, no enough data in the stream")
}

element.EnumConstValue = &EnumConstValue{
TypeNameIndex: binary.BigEndian.Uint16(bs[:2]),
ConstNameIndex: binary.BigEndian.Uint16(bs[2:]),
}
case 'c':
bs, err = stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read ElementValue ClassInfoIndex failed, no enough data in the stream")
}

element.ClassInfoIndex = binary.BigEndian.Uint16(bs)
case '@':
annotation, err := NewAnnotation(stream)
if err != nil {
return nil, fmt.Errorf("read ElementValue AnnotationValue failed, caused by: %v", err)
}

element.AnnotationValue = annotation
case '[':
bs, err = stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read ElementValue ArrayValue failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
subElement, err := NewElementValue(stream)
if err != nil {
return nil, fmt.Errorf("read ElementValue ArrayValue failed, caused by: %v", err)
}

element.ArrayValue = append(element.ArrayValue, subElement)
}
}

return element, nil
}

0 comments on commit 95e0399

Please sign in to comment.