aboutsummaryrefslogtreecommitdiff
path: root/libraries/pack200
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/pack200')
-rw-r--r--libraries/pack200/CMakeLists.txt39
-rw-r--r--libraries/pack200/LICENSE347
-rw-r--r--libraries/pack200/anti200.cpp43
-rw-r--r--libraries/pack200/include/unpack200.h36
-rw-r--r--libraries/pack200/src/bands.cpp423
-rw-r--r--libraries/pack200/src/bands.h489
-rw-r--r--libraries/pack200/src/bytes.cpp217
-rw-r--r--libraries/pack200/src/bytes.h286
-rw-r--r--libraries/pack200/src/coding.cpp1044
-rw-r--r--libraries/pack200/src/coding.h247
-rw-r--r--libraries/pack200/src/constants.h442
-rw-r--r--libraries/pack200/src/defines.h65
-rw-r--r--libraries/pack200/src/unpack.cpp4793
-rw-r--r--libraries/pack200/src/unpack.h547
-rw-r--r--libraries/pack200/src/unpack200.cpp162
-rw-r--r--libraries/pack200/src/utils.cpp71
-rw-r--r--libraries/pack200/src/utils.h53
-rw-r--r--libraries/pack200/src/zip.cpp589
-rw-r--r--libraries/pack200/src/zip.h110
19 files changed, 10003 insertions, 0 deletions
diff --git a/libraries/pack200/CMakeLists.txt b/libraries/pack200/CMakeLists.txt
new file mode 100644
index 00000000..b060905b
--- /dev/null
+++ b/libraries/pack200/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(unpack200)
+
+option(PACK200_BUILD_BINARY "Build a tiny utility that decompresses pack200 streams" OFF)
+
+# Find ZLIB for quazip
+find_package(ZLIB REQUIRED)
+
+set(PACK200_SRC
+ include/unpack200.h
+ src/bands.cpp
+ src/bands.h
+ src/bytes.cpp
+ src/bytes.h
+ src/coding.cpp
+ src/coding.h
+ src/constants.h
+ src/defines.h
+ src/unpack200.cpp
+ src/unpack.cpp
+ src/unpack.h
+ src/utils.cpp
+ src/utils.h
+ src/zip.cpp
+ src/zip.h
+)
+
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+add_library(unpack200 STATIC ${PACK200_SRC})
+target_include_directories(unpack200 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" PRIVATE ${ZLIB_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/src")
+
+target_link_libraries(unpack200 ${ZLIB_LIBRARIES})
+
+if(PACK200_BUILD_BINARY)
+ add_executable(anti200 anti200.cpp)
+ target_link_libraries(anti200 unpack200)
+endif()
diff --git a/libraries/pack200/LICENSE b/libraries/pack200/LICENSE
new file mode 100644
index 00000000..b40a0f45
--- /dev/null
+++ b/libraries/pack200/LICENSE
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it. (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have. You must
+make sure that they, too, receive or can get the source code. And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License. The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language. (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope. The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program). Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+ a) You must cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in whole or
+ in part contains or is derived from the Program or any part thereof, to be
+ licensed as a whole at no charge to all third parties under the terms of
+ this License.
+
+ c) If the modified program normally reads commands interactively when run,
+ you must cause it, when started running for such interactive use in the
+ most ordinary way, to print or display an announcement including an
+ appropriate copyright notice and a notice that there is no warranty (or
+ else, saying that you provide a warranty) and that users may redistribute
+ the program under these conditions, and telling the user how to view a copy
+ of this License. (Exception: if the Program itself is interactive but does
+ not normally print such an announcement, your work based on the Program is
+ not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works. But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable source
+ code, which must be distributed under the terms of Sections 1 and 2 above
+ on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three years, to
+ give any third party, for a charge no more than your cost of physically
+ performing source distribution, a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of Sections 1
+ and 2 above on a medium customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer to
+ distribute corresponding source code. (This alternative is allowed only
+ for noncommercial distribution and only if you received the program in
+ object code or executable form with such an offer, in accord with
+ Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable. However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License. Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License. However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works. These actions are prohibited by law if you do not
+accept this License. Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein. You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License. If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded. In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time. Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+ One line to give the program's name and a brief idea of what it does.
+
+ Copyright (C) <year> <name of author>
+
+ 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 2 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, write to the Free Software Foundation, Inc., 59
+ Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+ with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
+ software, and you are welcome to redistribute it under certain conditions;
+ type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. Here
+is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ 'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ signature of Ty Coon, 1 April 1989
+
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+ Linking this library statically or dynamically with other modules is making
+ a combined work based on this library. Thus, the terms and conditions of
+ the GNU General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,
+ and to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent module,
+ the terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library. If
+ you modify this library, you may extend this exception to your version of
+ the library, but you are not obligated to do so. If you do not wish to do
+ so, delete this exception statement from your version.
diff --git a/libraries/pack200/anti200.cpp b/libraries/pack200/anti200.cpp
new file mode 100644
index 00000000..1e1ec0c8
--- /dev/null
+++ b/libraries/pack200/anti200.cpp
@@ -0,0 +1,43 @@
+/*
+ * This is trivial. Do what thou wilt with it. Public domain.
+ */
+
+#include <stdexcept>
+#include <iostream>
+#include "unpack200.h"
+
+int main(int argc, char **argv)
+{
+ if (argc != 3)
+ {
+ std::cerr << "Simple pack200 unpacker!" << std::endl << "Run like this:" << std::endl
+ << " " << argv[0] << " input.jar.lzma output.jar" << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ FILE *input = fopen(argv[1], "rb");
+ FILE *output = fopen(argv[2], "wb");
+ if (!input)
+ {
+ std::cerr << "Can't open input file";
+ return EXIT_FAILURE;
+ }
+ if (!output)
+ {
+ fclose(output);
+ std::cerr << "Can't open output file";
+ return EXIT_FAILURE;
+ }
+ try
+ {
+ unpack_200(input, output);
+ }
+ catch (std::runtime_error &e)
+ {
+ std::cerr << "Bad things happened: " << e.what() << std::endl;
+ fclose(input);
+ fclose(output);
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/libraries/pack200/include/unpack200.h b/libraries/pack200/include/unpack200.h
new file mode 100644
index 00000000..9c3eda2d
--- /dev/null
+++ b/libraries/pack200/include/unpack200.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#pragma once
+#include <string>
+
+/**
+ * @brief Unpack a PACK200 file
+ *
+ * @param input_path Path to the input file in PACK200 format. System native string encoding.
+ * @param output_path Path to the output file in PACK200 format. System native string encoding.
+ * @throw std::runtime_error for any error encountered
+ */
+void unpack_200(FILE * input_path, FILE * output_path);
diff --git a/libraries/pack200/src/bands.cpp b/libraries/pack200/src/bands.cpp
new file mode 100644
index 00000000..1608d838
--- /dev/null
+++ b/libraries/pack200/src/bands.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -*- C++ -*-
+// Small program for unpacking specially compressed Java packages.
+// John R. Rose
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include "defines.h"
+#include "bytes.h"
+#include "utils.h"
+#include "coding.h"
+#include "bands.h"
+
+#include "constants.h"
+#include "unpack.h"
+
+void band::readData(int expectedLength)
+{
+ assert(expectedLength >= 0);
+ assert(vs[0].cmk == cmk_ERROR);
+ if (expectedLength != 0)
+ {
+ assert(length == 0);
+ length = expectedLength;
+ }
+ if (length == 0)
+ {
+ assert((rplimit = cm.vs0.rp = u->rp) != nullptr);
+ return;
+ }
+ assert(length > 0);
+
+ bool is_BYTE1 = (defc->spec == BYTE1_spec);
+
+ if (is_BYTE1)
+ {
+ // No possibility of coding change. Sizing is exact.
+ u->ensure_input(length);
+ }
+ else
+ {
+ // Make a conservatively generous estimate of band size in bytes.
+ // Assume B == 5 everywhere.
+ // Assume awkward pop with all {U} values (2*5 per value)
+ int64_t generous = (int64_t)length * (B_MAX * 3 + 1) + C_SLOP;
+ u->ensure_input(generous);
+ }
+
+ // Read one value to see what it might be.
+ int XB = _meta_default;
+ if (!is_BYTE1)
+ {
+ // must be a variable-length coding
+ assert(defc->B() > 1 && defc->L() > 0);
+
+ value_stream xvs;
+ coding *valc = defc;
+ if (valc->D() != 0)
+ {
+ valc = coding::findBySpec(defc->B(), defc->H(), defc->S());
+ assert(!valc->isMalloc);
+ }
+ xvs.init(u->rp, u->rplimit, valc);
+ int X = xvs.getInt();
+ if (valc->S() != 0)
+ {
+ assert(valc->min <= -256);
+ XB = -1 - X;
+ }
+ else
+ {
+ int L = valc->L();
+ assert(valc->max >= L + 255);
+ XB = X - L;
+ }
+ if (0 <= XB && XB < 256)
+ {
+ // Skip over the escape value.
+ u->rp = xvs.rp;
+ }
+ else
+ {
+ // No, it's still default.
+ XB = _meta_default;
+ }
+ }
+
+ if (XB <= _meta_canon_max)
+ {
+ byte XB_byte = (byte)XB;
+ byte *XB_ptr = &XB_byte;
+ cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, nullptr);
+ }
+ else
+ {
+ assert(u->meta_rp != nullptr);
+ // Scribble the initial byte onto the band.
+ byte *save_meta_rp = --u->meta_rp;
+ byte save_meta_xb = (*save_meta_rp);
+ (*save_meta_rp) = (byte)XB;
+ cm.init(u->rp, u->rplimit, u->meta_rp, 0, defc, length, nullptr);
+ (*save_meta_rp) = save_meta_xb; // put it back, just to be tidy
+ }
+ rplimit = u->rp;
+
+ rewind();
+}
+
+void band::setIndex(cpindex *ix_)
+{
+ assert(ix_ == nullptr || ixTag == ix_->ixTag);
+ ix = ix_;
+}
+void band::setIndexByTag(byte tag)
+{
+ setIndex(u->cp.getIndex(tag));
+}
+
+entry *band::getRefCommon(cpindex *ix_, bool nullOKwithCaller)
+{
+ assert(ix_->ixTag == ixTag ||
+ (ixTag == CONSTANT_Literal && ix_->ixTag >= CONSTANT_Integer &&
+ ix_->ixTag <= CONSTANT_String));
+ int n = vs[0].getInt() - nullOK;
+ // Note: band-local nullOK means nullptr encodes as 0.
+ // But nullOKwithCaller means caller is willing to tolerate a nullptr.
+ entry *ref = ix_->get(n);
+ if (ref == nullptr && !(nullOKwithCaller && n == -1))
+ unpack_abort(n == -1 ? "nullptr ref" : "bad ref");
+ return ref;
+}
+
+int64_t band::getLong(band &lo_band, bool have_hi)
+{
+ band &hi_band = (*this);
+ assert(lo_band.bn == hi_band.bn + 1);
+ uint32_t lo = lo_band.getInt();
+ if (!have_hi)
+ {
+ assert(hi_band.length == 0);
+ return makeLong(0, lo);
+ }
+ uint32_t hi = hi_band.getInt();
+ return makeLong(hi, lo);
+}
+
+int band::getIntTotal()
+{
+ if (length == 0)
+ return 0;
+ if (total_memo > 0)
+ return total_memo - 1;
+ int total = getInt();
+ // overflow checks require that none of the addends are <0,
+ // and that the partial sums never overflow (wrap negative)
+ if (total < 0)
+ {
+ unpack_abort("overflow detected");
+ }
+ for (int k = length - 1; k > 0; k--)
+ {
+ int prev_total = total;
+ total += vs[0].getInt();
+ if (total < prev_total)
+ {
+ unpack_abort("overflow detected");
+ }
+ }
+ rewind();
+ total_memo = total + 1;
+ return total;
+}
+
+int band::getIntCount(int tag)
+{
+ if (length == 0)
+ return 0;
+ if (tag >= HIST0_MIN && tag <= HIST0_MAX)
+ {
+ if (hist0 == nullptr)
+ {
+ // Lazily calculate an approximate histogram.
+ hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN) + 1);
+ for (int k = length; k > 0; k--)
+ {
+ int x = vs[0].getInt();
+ if (x >= HIST0_MIN && x <= HIST0_MAX)
+ hist0[x - HIST0_MIN] += 1;
+ }
+ rewind();
+ }
+ return hist0[tag - HIST0_MIN];
+ }
+ int total = 0;
+ for (int k = length; k > 0; k--)
+ {
+ total += (vs[0].getInt() == tag) ? 1 : 0;
+ }
+ rewind();
+ return total;
+}
+
+#define INDEX_INIT(tag, nullOK, subindex) ((tag) + (subindex) * SUBINDEX_BIT + (nullOK) * 256)
+
+#define INDEX(tag) INDEX_INIT(tag, 0, 0)
+#define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0)
+#define SUB_INDEX(tag) INDEX_INIT(tag, 0, 1)
+#define NO_INDEX 0
+
+struct band_init
+{
+ int defc;
+ int index;
+};
+
+#define BAND_INIT(name, cspec, ix) \
+ { \
+ cspec, ix \
+ }
+
+const band_init all_band_inits[] =
+ {
+ // BAND_INIT(archive_magic, BYTE1_spec, 0),
+ // BAND_INIT(archive_header, UNSIGNED5_spec, 0),
+ // BAND_INIT(band_headers, BYTE1_spec, 0),
+ BAND_INIT(cp_Utf8_prefix, DELTA5_spec, 0), BAND_INIT(cp_Utf8_suffix, UNSIGNED5_spec, 0),
+ BAND_INIT(cp_Utf8_chars, CHAR3_spec, 0), BAND_INIT(cp_Utf8_big_suffix, DELTA5_spec, 0),
+ BAND_INIT(cp_Utf8_big_chars, DELTA5_spec, 0), BAND_INIT(cp_Int, UDELTA5_spec, 0),
+ BAND_INIT(cp_Float, UDELTA5_spec, 0), BAND_INIT(cp_Long_hi, UDELTA5_spec, 0),
+ BAND_INIT(cp_Long_lo, DELTA5_spec, 0), BAND_INIT(cp_Double_hi, UDELTA5_spec, 0),
+ BAND_INIT(cp_Double_lo, DELTA5_spec, 0),
+ BAND_INIT(cp_String, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Class, UDELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Signature_form, DELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Signature_classes, UDELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Descr_name, DELTA5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(cp_Descr_type, UDELTA5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(cp_Field_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Field_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(cp_Method_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(attr_definition_headers, BYTE1_spec, 0),
+ BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)),
+ BAND_INIT(ic_this_class, UDELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(ic_flags, UNSIGNED5_spec, 0),
+ BAND_INIT(ic_outer_class, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Class)),
+ BAND_INIT(ic_name, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Utf8)),
+ BAND_INIT(class_this, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_super, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_interface_count, DELTA5_spec, 0),
+ BAND_INIT(class_interface, DELTA5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(class_field_count, DELTA5_spec, 0),
+ BAND_INIT(class_method_count, DELTA5_spec, 0),
+ BAND_INIT(field_descr, DELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(field_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(field_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_Literal)),
+ BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(field_metadata_bands, -1, -1), BAND_INIT(field_attr_bands, -1, -1),
+ BAND_INIT(method_descr, MDELTA5_spec, INDEX(CONSTANT_NameandType)),
+ BAND_INIT(method_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(method_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(method_attr_calls, UNSIGNED5_spec, 0),
+ BAND_INIT(method_Exceptions_N, UNSIGNED5_spec, 0),
+ BAND_INIT(method_Exceptions_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)),
+ BAND_INIT(method_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)),
+ BAND_INIT(method_metadata_bands, -1, -1), BAND_INIT(method_attr_bands, -1, -1),
+ BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0),
+ BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_count, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr_indexes, UNSIGNED5_spec, 0),
+ BAND_INIT(class_attr