Skip to content

Commit

Permalink
continue to write attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
phith0n committed Apr 5, 2024
1 parent 42ab515 commit 9120100
Show file tree
Hide file tree
Showing 19 changed files with 267 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ linters-settings:
xml: snake
form: snake
msgpack: snake
staticcheck:
checks: ["all"]
10 changes: 5 additions & 5 deletions class/annotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
)

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

type ElementValuePair struct {
ElementNameIndex uint16
ElementValue *ElementValue
Value *ElementValue
}

func NewAnnotation(stream *commons.Stream) (*Annotation, error) {
Expand All @@ -22,11 +22,11 @@ func NewAnnotation(stream *commons.Stream) (*Annotation, error) {
return nil, fmt.Errorf("read Annotation failed, no enough data in the stream")
}

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

for i := uint16(0); i < binary.BigEndian.Uint16(bs[2:]); i++ {
for i := uint16(0); i < length; 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)
Expand All @@ -35,7 +35,7 @@ func NewAnnotation(stream *commons.Stream) (*Annotation, error) {
pair := &ElementValuePair{
ElementNameIndex: binary.BigEndian.Uint16(bs),
}
pair.ElementValue, err = NewElementValue(stream)
pair.Value, err = NewElementValue(stream)
if err != nil {
return nil, fmt.Errorf("read Annotation ElementValuePair[%d] failed, caused by: %v", i, err)
}
Expand Down
22 changes: 22 additions & 0 deletions class/attr_annotation_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package class

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

type AttrAnnotationDefault struct {
*AttributeBase

DefaultValue *ElementValue
}

func (a *AttrAnnotationDefault) readInfo(stream *commons.Stream) error {
value, err := NewElementValue(stream)
if err != nil {
return fmt.Errorf("read AttrAnnotationDefault failed, caused by: %v", err)
}

a.DefaultValue = value
return nil
}
3 changes: 2 additions & 1 deletion class/attr_bootstrap_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ func (a *AttrBootstrapMethods) readBootstrapMethod(stream *commons.Stream) (*Boo
return nil, fmt.Errorf("read AttrBootstrapMethods BootstrapMethod failed, no enough data in the stream")
}

length := binary.BigEndian.Uint16(bs[2:])
method := &BootstrapMethod{
BootstrapMethodRef: binary.BigEndian.Uint16(bs[:2]),
}
for i := uint16(0); i < binary.BigEndian.Uint16(bs[2:]); i++ {
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read AttrBootstrapMethods BootstrapMethod argument[%d] failed, no enough data in the stream", i)
Expand Down
8 changes: 4 additions & 4 deletions class/attr_innerclasses.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type InnerClass struct {

// The value of the InnerClassAccessFlags item is a mask of flags used to denote access permissions to
// and properties of class or interface C as declared in the source code from which this class file was compiled.
InnerClassAccessFlags uint16
InnerClassAccessFlags ClassAccessFlag
}

func (a *AttrInnerClasses) readInfo(stream *commons.Stream) error {
Expand Down Expand Up @@ -56,11 +56,11 @@ func (a *AttrInnerClasses) readInnerClass(stream *commons.Stream) (*InnerClass,
InnerClassInfo: binary.BigEndian.Uint16(bs[:2]),
OuterClassInfo: binary.BigEndian.Uint16(bs[2:4]),
InnerClassIndex: binary.BigEndian.Uint16(bs[4:6]),
InnerClassAccessFlags: binary.BigEndian.Uint16(bs[6:]),
InnerClassAccessFlags: ClassAccessFlag(binary.BigEndian.Uint16(bs[6:])),
}
return c, nil
}

func (ic *InnerClass) HasFlag(flag uint16) bool {
return (flag & ic.InnerClassAccessFlags) == flag
func (ic *InnerClass) HasFlag(flag ClassAccessFlag) bool {
return ic.InnerClassAccessFlags.HasAccessFlag(flag)
}
3 changes: 2 additions & 1 deletion class/attr_linenumber_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ func (a *AttrLineNumberTable) readInfo(stream *commons.Stream) error {
return fmt.Errorf("read AttrLineNumberTable failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(4)
if err != nil {
return fmt.Errorf("read AttrLineNumberTable line numbers failed, no enough data in the stream")
Expand Down
3 changes: 2 additions & 1 deletion class/attr_localvartable.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func (a *AttrLocalVariableTable) readInfo(stream *commons.Stream) error {
return fmt.Errorf("read AttrLocalVariableTable failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(10)
if err != nil {
return fmt.Errorf("read AttrLocalVariableTable tables failed, no enough data in the stream")
Expand Down
3 changes: 2 additions & 1 deletion class/attr_localvartypetable.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ func (a *AttrLocalVariableTypeTable) readInfo(stream *commons.Stream) error {
return fmt.Errorf("read AttrLocalVariableTypeTable failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(10)
if err != nil {
return fmt.Errorf("read AttrLocalVariableTypeTable tables failed, no enough data in the stream")
Expand Down
40 changes: 40 additions & 0 deletions class/attr_method_parameters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package class

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

// AttrMethodParameters https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms-4.7.24
type AttrMethodParameters struct {
*AttributeBase

Parameters []*MethodParameter
}

type MethodParameter struct {
NameIndex uint16
AccessFlags ParameterAccessFlag
}

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

length := bs[0]
for i := uint8(0); i < length; i++ {
bs, err = stream.ReadN(4)
if err != nil {
return fmt.Errorf("read AttrMethodParameters NameIndex and AccessFlag failed, no enough data in the stream")
}

a.Parameters = append(a.Parameters, &MethodParameter{
NameIndex: binary.BigEndian.Uint16(bs[:2]),
AccessFlags: ParameterAccessFlag(binary.BigEndian.Uint16(bs[2:])),
})
}
return nil
}
111 changes: 111 additions & 0 deletions class/attr_module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package class

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

type AttrModule struct {
*AttributeBase

ModuleName uint16
ModuleFlags uint16
ModuleVersionIndex uint16

Requires []*ModuleRequires
Exports []*ModuleExports
Opens []*ModuleOpens
UsesIndex []uint16
Provides []*ModuleProvides
}

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

a.ModuleName = binary.BigEndian.Uint16(bs[:2])
a.ModuleFlags = binary.BigEndian.Uint16(bs[2:4])
a.ModuleVersionIndex = binary.BigEndian.Uint16(bs[4:])
return nil
}

type ModuleRequires struct {
RequiresIndex uint16
RequiresFlags uint16
RequiresVersionIndex uint16
}

func (a *AttrModule) readRequires(stream *commons.Stream) ([]*ModuleRequires, error) {

Check failure on line 41 in class/attr_module.go

View workflow job for this annotation

GitHub Actions / lint

func `(*AttrModule).readRequires` is unused (unused)
bs, err := stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read AttrModule Requires failed, no enough data in the stream")
}

var requires []*ModuleRequires
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(6)
if err != nil {
return nil, fmt.Errorf("read AttrModule Requires[%d] failed, no enough data in the stream", i)
}

requires = append(requires, &ModuleRequires{
RequiresIndex: binary.BigEndian.Uint16(bs[:2]),
RequiresFlags: binary.BigEndian.Uint16(bs[2:4]),
RequiresVersionIndex: binary.BigEndian.Uint16(bs[4:]),
})
}
return requires, nil
}

type ModuleExports struct {
ExportsIndex uint16
ExportsFlags uint16
ExportsToIndex []uint16
}

func (a *AttrModule) readExports(stream *commons.Stream) ([]*ModuleExports, error) {

Check failure on line 70 in class/attr_module.go

View workflow job for this annotation

GitHub Actions / lint

func `(*AttrModule).readExports` is unused (unused)
bs, err := stream.ReadN(2)
if err != nil {
return nil, fmt.Errorf("read AttrModule Exports failed, no enough data in the stream")
}

var exports []*ModuleExports
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(6)
if err != nil {
return nil, fmt.Errorf("read AttrModule Exports[%d] failed, no enough data in the stream", i)
}

export := &ModuleExports{
ExportsIndex: binary.BigEndian.Uint16(bs[:2]),
ExportsFlags: binary.BigEndian.Uint16(bs[2:4]),
}

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

export.ExportsToIndex = append(export.ExportsToIndex, binary.BigEndian.Uint16(data))
}
exports = append(exports, export)
}
return exports, nil
}

type ModuleOpens struct {
OpensIndex uint16
OpensFlags uint16
OpensToIndex []uint16
}

type ModuleProvides struct {
ProvidesIndex uint16
ProvidesWithIndex []uint16
}
3 changes: 2 additions & 1 deletion class/attr_nest_members.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func (a *AttrNestMembers) readInfo(stream *commons.Stream) error {
return fmt.Errorf("read AttrNestMembers failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(2)
if err != nil {
return fmt.Errorf("read AttrNestMembers class[%d] failed, no enough data in the stream", i)
Expand Down
3 changes: 2 additions & 1 deletion class/attr_permitted_subclasses.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func (a *AttrPermittedSubclasses) readInfo(stream *commons.Stream) error {
return fmt.Errorf("read AttrPermittedSubclasses failed, no enough data in the stream")
}

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
length := binary.BigEndian.Uint16(bs)
for i := uint16(0); i < length; i++ {
bs, err = stream.ReadN(2)
if err != nil {
return fmt.Errorf("read AttrPermittedSubclasses class[%d] failed, no enough data in the stream", i)
Expand Down
33 changes: 33 additions & 0 deletions class/attr_runtime_invisible_type_annotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package class

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

// AttrRuntimeInvisibleTypeAnnotations https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms-4.7.21
type AttrRuntimeInvisibleTypeAnnotations struct {
*AttributeBase

Annotations []*TypeAnnotation
}

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

for i := uint16(0); i < binary.BigEndian.Uint16(bs); i++ {
var annotation *TypeAnnotation
annotation, err = NewTypeAnnotation(stream)
if err != nil {
return fmt.Errorf("read AttrRuntimeInvisibleTypeAnnotations TypeAnnotation[%d] failed, caused by: %v", i, err)
}

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

return nil
}
2 changes: 1 addition & 1 deletion class/constant_interface_methodref.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantInterfaceMethodRef struct {
}

func (c *ConstantInterfaceMethodRef) ToBytes() []byte {
var bs = []byte{CONSTANT_INTERFACE_METHOD_REF}
var bs = []byte{ConstantInterfaceMethodRefInfo}
bs = append(bs, commons.NumberToBytes(c.ClassIndex)...)
bs = append(bs, commons.NumberToBytes(c.NameAndTypeIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_str.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantString struct {
}

func (c *ConstantString) ToBytes() []byte {
var bs = []byte{CONSTANT_STRING_INGFO}
var bs = []byte{ConstantStringInfo}
bs = append(bs, commons.NumberToBytes(c.StringIndex)...)
return bs
}
Expand Down
13 changes: 13 additions & 0 deletions class/parameter_access.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package class

type ParameterAccessFlag uint16

const (
ParameterAccFinal ParameterAccessFlag = 0x0010
ParameterAccSynthetic ParameterAccessFlag = 0x1000
ParameterAccMandated ParameterAccessFlag = 0x8000
)

func (caf ParameterAccessFlag) HasAccessFlag(flag ParameterAccessFlag) bool {
return (flag & caf) == flag
}
Loading

0 comments on commit 9120100

Please sign in to comment.