diff options
Diffstat (limited to 'meshmc/libraries/classparser/src/classfile.h')
| -rw-r--r-- | meshmc/libraries/classparser/src/classfile.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/meshmc/libraries/classparser/src/classfile.h b/meshmc/libraries/classparser/src/classfile.h new file mode 100644 index 0000000000..0832c8039d --- /dev/null +++ b/meshmc/libraries/classparser/src/classfile.h @@ -0,0 +1,169 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once +#include "membuffer.h" +#include "constants.h" +#include "annotations.h" +#include <map> +namespace java +{ + /** + * Class representing a Java .class file + */ + class classfile : public util::membuffer + { + public: + classfile(char* data, std::size_t size) : membuffer(data, size) + { + valid = false; + is_synthetic = false; + read_be(magic); + if (magic != 0xCAFEBABE) + throw new classfile_exception(); + read_be(minor_version); + read_be(major_version); + constants.load(*this); + read_be(access_flags); + read_be(this_class); + read_be(super_class); + + // Interfaces + uint16_t iface_count = 0; + read_be(iface_count); + while (iface_count) { + uint16_t iface; + read_be(iface); + interfaces.push_back(iface); + iface_count--; + } + + // Fields + // read fields (and attributes from inside fields) (and possible + // inner classes. yay for recursion!) for now though, we will ignore + // all attributes + /* + * field_info + * { + * u2 access_flags; + * u2 name_index; + * u2 descriptor_index; + * u2 attributes_count; + * attribute_info attributes[attributes_count]; + * } + */ + uint16_t field_count = 0; + read_be(field_count); + while (field_count) { + // skip field stuff + skip(6); + // and skip field attributes + uint16_t attr_count = 0; + read_be(attr_count); + while (attr_count) { + skip(2); + uint32_t attr_length = 0; + read_be(attr_length); + skip(attr_length); + attr_count--; + } + field_count--; + } + + // class methods + /* + * method_info + * { + * u2 access_flags; + * u2 name_index; + * u2 descriptor_index; + * u2 attributes_count; + * attribute_info attributes[attributes_count]; + * } + */ + uint16_t method_count = 0; + read_be(method_count); + while (method_count) { + skip(6); + // and skip method attributes + uint16_t attr_count = 0; + read_be(attr_count); + while (attr_count) { + skip(2); + uint32_t attr_length = 0; + read_be(attr_length); + skip(attr_length); + attr_count--; + } + method_count--; + } + + // class attributes + // there are many kinds of attributes. this is just the generic + // wrapper structure. type is decided by attribute name. extensions + // to the standard are *possible* class annotations are one kind of + // a attribute (one per class) + /* + * attribute_info + * { + * u2 attribute_name_index; + * u4 attribute_length; + * u1 info[attribute_length]; + * } + */ + uint16_t class_attr_count = 0; + read_be(class_attr_count); + while (class_attr_count) { + uint16_t name_idx = 0; + read_be(name_idx); + uint32_t attr_length = 0; + read_be(attr_length); + + auto name = constants[name_idx]; + if (name.str_data == "RuntimeVisibleAnnotations") { + uint16_t num_annotations = 0; + read_be(num_annotations); + while (num_annotations) { + visible_class_annotations.push_back( + annotation::read(*this, constants)); + num_annotations--; + } + } else + skip(attr_length); + class_attr_count--; + } + valid = true; + }; + bool valid; + bool is_synthetic; + uint32_t magic; + uint16_t minor_version; + uint16_t major_version; + constant_pool constants; + uint16_t access_flags; + uint16_t this_class; + uint16_t super_class; + // interfaces this class implements ? must be. investigate. + std::vector<uint16_t> interfaces; + // FIXME: doesn't free up memory on delete + java::annotation_table visible_class_annotations; + }; +} // namespace java
\ No newline at end of file |
