diff options
Diffstat (limited to 'src/main/java/com/android/apkzlib/zip/GPFlags.java')
-rw-r--r-- | src/main/java/com/android/apkzlib/zip/GPFlags.java | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/main/java/com/android/apkzlib/zip/GPFlags.java b/src/main/java/com/android/apkzlib/zip/GPFlags.java new file mode 100644 index 0000000..40965e8 --- /dev/null +++ b/src/main/java/com/android/apkzlib/zip/GPFlags.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.apkzlib.zip; + +import com.android.annotations.NonNull; + +import java.io.IOException; + +/** + * General purpose bit flags. Contains the encoding of the zip's general purpose bits. + * + * <p>We don't really care about the method bit(s). These are bits 1 and 2. Here are the values: + * <ul> + * <li>0 (00): Normal (-en) compression option was used. + * <li>1 (01): Maximum (-exx/-ex) compression option was used. + * <li>2 (10): Fast (-ef) compression option was used. + * <li>3 (11): Super Fast (-es) compression option was used. + * </ul> + */ +class GPFlags { + + /** + * Is the entry encrypted? + */ + private static final int BIT_ENCRYPTION = 1; + + /** + * Has CRC computation been deferred and, therefore, does a data description block exist? + */ + private static final int BIT_DEFERRED_CRC = (1 << 3); + + /** + * Is enhanced deflating used? + */ + private static final int BIT_ENHANCED_DEFLATING = (1 << 4); + + /** + * Does the entry contain patched data? + */ + private static final int BIT_PATCHED_DATA = (1 << 5); + + /** + * Is strong encryption used? + */ + private static final int BIT_STRONG_ENCRYPTION = (1 << 6) | (1 << 13); + + /** + * If this bit is set the filename and comment fields for this file must be encoded using UTF-8. + */ + private static final int BIT_EFS = (1 << 11); + + /** + * Unused bits. + */ + private static final int BIT_UNUSED = (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) + | (1 << 14) | (1 << 15); + /** + * Bit flag value. + */ + private final long mValue; + + /** + * Has the CRC computation beeen deferred? + */ + private boolean mDeferredCrc; + + /** + * Is the file name encoded in UTF-8? + */ + private boolean mUtf8FileName; + + /** + * Creates a new flags object. + * + * @param value the value of the bit mask + */ + private GPFlags(long value) { + mValue = value; + + mDeferredCrc = ((value & BIT_DEFERRED_CRC) != 0); + mUtf8FileName = ((value & BIT_EFS) != 0); + } + + /** + * Obtains the flags value. + * + * @return the value of the bit mask + */ + public long getValue() { + return mValue; + } + + /** + * Is the CRC computation deferred? + * + * @return is the CRC computation deferred? + */ + public boolean isDeferredCrc() { + return mDeferredCrc; + } + + /** + * Is the file name encoded in UTF-8? + * + * @return is the file name encoded in UTF-8? + */ + public boolean isUtf8FileName() { + return mUtf8FileName; + } + + /** + * Creates a new bit mask. + * + * @param utf8Encoding should UTF-8 encoding be used? + * @return the new bit mask + */ + @NonNull + static GPFlags make(boolean utf8Encoding) { + long flags = 0; + + if (utf8Encoding) { + flags |= BIT_EFS; + } + + return new GPFlags(flags); + } + + /** + * Creates the flag information from a byte. This method will also validate that only + * supported options are defined in the flag. + * + * @param bits the bit mask + * @return the created flag information + * @throws IOException unsupported options are used in the bit mask + */ + @NonNull + static GPFlags from(long bits) throws IOException { + if ((bits & BIT_ENCRYPTION) != 0) { + throw new IOException("Zip files with encrypted of entries not supported."); + } + + if ((bits & BIT_ENHANCED_DEFLATING) != 0) { + throw new IOException("Enhanced deflating not supported."); + } + + if ((bits & BIT_PATCHED_DATA) != 0) { + throw new IOException("Compressed patched data not supported."); + } + + if ((bits & BIT_STRONG_ENCRYPTION) != 0) { + throw new IOException("Strong encryption not supported."); + } + + if ((bits & BIT_UNUSED) != 0) { + throw new IOException("Unused bits set in directory entry. Weird. I don't know what's " + + "going on."); + } + + if ((bits & 0xffffffff00000000L) != 0) { + throw new IOException("Unsupported bits after 32."); + } + + return new GPFlags(bits); + } +} |