fix broken fillRegenerationBuffer/fillScreenArray attempt to handle missing attributes; fix setfield outside screen boundaries
line source
+ − /* -*-mode:java; c-basic-offset:2; -*- */
+ − /*
+ − Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
+ −
+ − Redistribution and use in source and binary forms, with or without
+ − modification, are permitted provided that the following conditions are met:
+ −
+ − 1. Redistributions of source code must retain the above copyright notice,
+ − this list of conditions and the following disclaimer.
+ −
+ − 2. Redistributions in binary form must reproduce the above copyright
+ − notice, this list of conditions and the following disclaimer in
+ − the documentation and/or other materials provided with the distribution.
+ −
+ − 3. The names of the authors may not be used to endorse or promote products
+ − derived from this software without specific prior written permission.
+ −
+ − THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ − INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ − FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ − INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ − INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ − LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ − OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ − LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ − NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ − EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ − */
+ − /*
+ − * This program is based on zlib-1.1.3, so all credit should go authors
+ − * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ − * and contributors of zlib.
+ − */
+ −
+ − package com.jcraft.jzlib;
+ −
+ − final class Inflate{
+ −
+ − static final private int MAX_WBITS=15; // 32K LZ77 window
+ −
+ − // preset dictionary flag in zlib header
+ − static final private int PRESET_DICT=0x20;
+ −
+ − static final int Z_NO_FLUSH=0;
+ − static final int Z_PARTIAL_FLUSH=1;
+ − static final int Z_SYNC_FLUSH=2;
+ − static final int Z_FULL_FLUSH=3;
+ − static final int Z_FINISH=4;
+ −
+ − static final private int Z_DEFLATED=8;
+ −
+ − static final private int Z_OK=0;
+ − static final private int Z_STREAM_END=1;
+ − static final private int Z_NEED_DICT=2;
+ − static final private int Z_ERRNO=-1;
+ − static final private int Z_STREAM_ERROR=-2;
+ − static final private int Z_DATA_ERROR=-3;
+ − static final private int Z_MEM_ERROR=-4;
+ − static final private int Z_BUF_ERROR=-5;
+ − static final private int Z_VERSION_ERROR=-6;
+ −
+ − static final private int METHOD=0; // waiting for method byte
+ − static final private int FLAG=1; // waiting for flag byte
+ − static final private int DICT4=2; // four dictionary check bytes to go
+ − static final private int DICT3=3; // three dictionary check bytes to go
+ − static final private int DICT2=4; // two dictionary check bytes to go
+ − static final private int DICT1=5; // one dictionary check byte to go
+ − static final private int DICT0=6; // waiting for inflateSetDictionary
+ − static final private int BLOCKS=7; // decompressing blocks
+ − static final private int CHECK4=8; // four check bytes to go
+ − static final private int CHECK3=9; // three check bytes to go
+ − static final private int CHECK2=10; // two check bytes to go
+ − static final private int CHECK1=11; // one check byte to go
+ − static final private int DONE=12; // finished check, done
+ − static final private int BAD=13; // got an error--stay here
+ −
+ − static final private int HEAD=14;
+ − static final private int LENGTH=15;
+ − static final private int TIME=16;
+ − static final private int OS=17;
+ − static final private int EXLEN=18;
+ − static final private int EXTRA=19;
+ − static final private int NAME=20;
+ − static final private int COMMENT=21;
+ − static final private int HCRC=22;
+ − static final private int FLAGS=23;
+ −
+ − static final int INFLATE_ANY=0x40000000;
+ −
+ − int mode; // current inflate mode
+ −
+ − // mode dependent information
+ − int method; // if FLAGS, method byte
+ −
+ − // if CHECK, check values to compare
+ − long was = -1; // computed check value
+ − long need; // stream check value
+ −
+ − // if BAD, inflateSync's marker bytes count
+ − int marker;
+ −
+ − // mode independent information
+ − int wrap; // flag for no wrapper
+ − // 0: no wrapper
+ − // 1: zlib header
+ − // 2: gzip header
+ − // 4: auto detection
+ −
+ − int wbits; // log2(window size) (8..15, defaults to 15)
+ −
+ − InfBlocks blocks; // current inflate_blocks state
+ −
+ − private final ZStream z;
+ −
+ − private int flags;
+ −
+ − private int need_bytes = -1;
+ − private byte[] crcbuf=new byte[4];
+ −
+ − GZIPHeader gheader = null;
+ −
+ − int inflateReset(){
+ − if(z == null) return Z_STREAM_ERROR;
+ −
+ − z.total_in = z.total_out = 0;
+ − z.msg = null;
+ − this.mode = HEAD;
+ − this.need_bytes = -1;
+ − this.blocks.reset();
+ − return Z_OK;
+ − }
+ −
+ − int inflateEnd(){
+ − if(blocks != null){
+ − blocks.free();
+ − }
+ − return Z_OK;
+ − }
+ −
+ − Inflate(ZStream z){
+ − this.z=z;
+ − }
+ −
+ − int inflateInit(int w){
+ − z.msg = null;
+ − blocks = null;
+ −
+ − // handle undocumented wrap option (no zlib header or check)
+ − wrap = 0;
+ − if(w < 0){
+ − w = - w;
+ − }
+ − else if((w&INFLATE_ANY) != 0){
+ − wrap = 4;
+ − w &= ~INFLATE_ANY;
+ − if(w < 48)
+ − w &= 15;
+ − }
+ − else if((w & ~31) != 0) { // for example, DEF_WBITS + 32
+ − wrap = 4; // zlib and gzip wrapped data should be accepted.
+ − w &= 15;
+ − }
+ − else {
+ − wrap = (w >> 4) + 1;
+ − if(w < 48)
+ − w &= 15;
+ − }
+ −
+ − if(w<8 ||w>15){
+ − inflateEnd();
+ − return Z_STREAM_ERROR;
+ − }
+ − if(blocks != null && wbits != w){
+ − blocks.free();
+ − blocks=null;
+ − }
+ −
+ − // set window size
+ − wbits=w;
+ −
+ − this.blocks=new InfBlocks(z, 1<<w);
+ −
+ − // reset state
+ − inflateReset();
+ −
+ − return Z_OK;
+ − }
+ −
+ − int inflate(int f){
+ − int hold = 0;
+ −
+ − int r;
+ − int b;
+ −
+ − if(z == null || z.next_in == null){
+ − if(f == Z_FINISH && this.mode==HEAD)
+ − return Z_OK;
+ − return Z_STREAM_ERROR;
+ − }
+ −
+ − f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+ − r = Z_BUF_ERROR;
+ − while (true){
+ −
+ − switch (this.mode){
+ − case HEAD:
+ − if(wrap==0){
+ − this.mode = BLOCKS;
+ − break;
+ − }
+ −
+ − try { r=readBytes(2, r, f); }
+ − catch(Return e){ return e.r; }
+ −
+ − if((wrap == 4 || (wrap&2)!=0) &&
+ − this.need == 0x8b1fL) { // gzip header
+ − if(wrap == 4){
+ − wrap = 2;
+ − }
+ − z.adler=new CRC32();
+ − checksum(2, this.need);
+ −
+ − if(gheader==null)
+ − gheader=new GZIPHeader();
+ −
+ − this.mode = FLAGS;
+ − break;
+ − }
+ −
+ − if((wrap&2) != 0){
+ − this.mode = BAD;
+ − z.msg = "incorrect header check";
+ − break;
+ − }
+ −
+ − flags = 0;
+ −
+ − this.method = ((int)this.need)&0xff;
+ − b=((int)(this.need>>8))&0xff;
+ −
+ − if(((wrap&1)==0 || // check if zlib header allowed
+ − (((this.method << 8)+b) % 31)!=0) &&
+ − (this.method&0xf)!=Z_DEFLATED){
+ − if(wrap == 4){
+ − z.next_in_index -= 2;
+ − z.avail_in += 2;
+ − z.total_in -= 2;
+ − wrap = 0;
+ − this.mode = BLOCKS;
+ − break;
+ − }
+ − this.mode = BAD;
+ − z.msg = "incorrect header check";
+ − // since zlib 1.2, it is allowted to inflateSync for this case.
+ − /*
+ − this.marker = 5; // can't try inflateSync
+ − */
+ − break;
+ − }
+ −
+ − if((this.method&0xf)!=Z_DEFLATED){
+ − this.mode = BAD;
+ − z.msg="unknown compression method";
+ − // since zlib 1.2, it is allowted to inflateSync for this case.
+ − /*
+ − this.marker = 5; // can't try inflateSync
+ − */
+ − break;
+ − }
+ −
+ − if(wrap == 4){
+ − wrap = 1;
+ − }
+ −
+ − if((this.method>>4)+8>this.wbits){
+ − this.mode = BAD;
+ − z.msg="invalid window size";
+ − // since zlib 1.2, it is allowted to inflateSync for this case.
+ − /*
+ − this.marker = 5; // can't try inflateSync
+ − */
+ − break;
+ − }
+ −
+ − z.adler=new Adler32();
+ −
+ − if((b&PRESET_DICT)==0){
+ − this.mode = BLOCKS;
+ − break;
+ − }
+ − this.mode = DICT4;
+ − case DICT4:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
+ − this.mode=DICT3;
+ − case DICT3:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
+ − this.mode=DICT2;
+ − case DICT2:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
+ − this.mode=DICT1;
+ − case DICT1:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need += (z.next_in[z.next_in_index++]&0xffL);
+ − z.adler.reset(this.need);
+ − this.mode = DICT0;
+ − return Z_NEED_DICT;
+ − case DICT0:
+ − this.mode = BAD;
+ − z.msg = "need dictionary";
+ − this.marker = 0; // can try inflateSync
+ − return Z_STREAM_ERROR;
+ − case BLOCKS:
+ − r = this.blocks.proc(r);
+ − if(r == Z_DATA_ERROR){
+ − this.mode = BAD;
+ − this.marker = 0; // can try inflateSync
+ − break;
+ − }
+ − if(r == Z_OK){
+ − r = f;
+ − }
+ − if(r != Z_STREAM_END){
+ − return r;
+ − }
+ − r = f;
+ − this.was=z.adler.getValue();
+ − this.blocks.reset();
+ − if(this.wrap==0){
+ − this.mode=DONE;
+ − break;
+ − }
+ − this.mode=CHECK4;
+ − case CHECK4:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
+ − this.mode=CHECK3;
+ − case CHECK3:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
+ − this.mode = CHECK2;
+ − case CHECK2:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
+ − this.mode = CHECK1;
+ − case CHECK1:
+ −
+ − if(z.avail_in==0)return r;r=f;
+ −
+ − z.avail_in--; z.total_in++;
+ − this.need+=(z.next_in[z.next_in_index++]&0xffL);
+ −
+ − if(flags!=0){ // gzip
+ − this.need = ((this.need&0xff000000)>>24 |
+ − (this.need&0x00ff0000)>>8 |
+ − (this.need&0x0000ff00)<<8 |
+ − (this.need&0x0000ffff)<<24)&0xffffffffL;
+ − }
+ −
+ − if(((int)(this.was)) != ((int)(this.need))){
+ − z.msg = "incorrect data check";
+ − // chack is delayed
+ − /*
+ − this.mode = BAD;
+ − this.marker = 5; // can't try inflateSync
+ − break;
+ − */
+ − }
+ − else if(flags!=0 && gheader!=null){
+ − gheader.crc = this.need;
+ − }
+ −
+ − this.mode = LENGTH;
+ − case LENGTH:
+ − if (wrap!=0 && flags!=0) {
+ −
+ − try { r=readBytes(4, r, f); }
+ − catch(Return e){ return e.r; }
+ −
+ − if(z.msg!=null && z.msg.equals("incorrect data check")){
+ − this.mode = BAD;
+ − this.marker = 5; // can't try inflateSync
+ − break;
+ − }
+ −
+ − if (this.need != (z.total_out & 0xffffffffL)) {
+ − z.msg = "incorrect length check";
+ − this.mode = BAD;
+ − break;
+ − }
+ − z.msg = null;
+ − }
+ − else {
+ − if(z.msg!=null && z.msg.equals("incorrect data check")){
+ − this.mode = BAD;
+ − this.marker = 5; // can't try inflateSync
+ − break;
+ − }
+ − }
+ −
+ − this.mode = DONE;
+ − case DONE:
+ − return Z_STREAM_END;
+ − case BAD:
+ − return Z_DATA_ERROR;
+ −
+ − case FLAGS:
+ −
+ − try { r=readBytes(2, r, f); }
+ − catch(Return e){ return e.r; }
+ −
+ − flags = ((int)this.need)&0xffff;
+ −
+ − if ((flags & 0xff) != Z_DEFLATED) {
+ − z.msg = "unknown compression method";
+ − this.mode = BAD;
+ − break;
+ − }
+ − if ((flags & 0xe000)!=0) {
+ − z.msg = "unknown header flags set";
+ − this.mode = BAD;
+ − break;
+ − }
+ −
+ − if ((flags & 0x0200)!=0){
+ − checksum(2, this.need);
+ − }
+ −
+ − this.mode = TIME;
+ −
+ − case TIME:
+ − try { r=readBytes(4, r, f); }
+ − catch(Return e){ return e.r; }
+ − if(gheader!=null)
+ − gheader.time = this.need;
+ − if ((flags & 0x0200)!=0){
+ − checksum(4, this.need);
+ − }
+ − this.mode = OS;
+ − case OS:
+ − try { r=readBytes(2, r, f); }
+ − catch(Return e){ return e.r; }
+ − if(gheader!=null){
+ − gheader.xflags = ((int)this.need)&0xff;
+ − gheader.os = (((int)this.need)>>8)&0xff;
+ − }
+ − if ((flags & 0x0200)!=0){
+ − checksum(2, this.need);
+ − }
+ − this.mode = EXLEN;
+ − case EXLEN:
+ − if ((flags & 0x0400)!=0) {
+ − try { r=readBytes(2, r, f); }
+ − catch(Return e){ return e.r; }
+ − if(gheader!=null){
+ − gheader.extra = new byte[((int)this.need)&0xffff];
+ − }
+ − if ((flags & 0x0200)!=0){
+ − checksum(2, this.need);
+ − }
+ − }
+ − else if(gheader!=null){
+ − gheader.extra=null;
+ − }
+ − this.mode = EXTRA;
+ −
+ − case EXTRA:
+ − if ((flags & 0x0400)!=0) {
+ − try {
+ − r=readBytes(r, f);
+ − if(gheader!=null){
+ − byte[] foo = tmp_string.toByteArray();
+ − tmp_string=null;
+ − if(foo.length == gheader.extra.length){
+ − System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
+ − }
+ − else{
+ − z.msg = "bad extra field length";
+ − this.mode = BAD;
+ − break;
+ − }
+ − }
+ − }
+ − catch(Return e){ return e.r; }
+ − }
+ − else if(gheader!=null){
+ − gheader.extra=null;
+ − }
+ − this.mode = NAME;
+ − case NAME:
+ − if ((flags & 0x0800)!=0) {
+ − try {
+ − r=readString(r, f);
+ − if(gheader!=null){
+ − gheader.name=tmp_string.toByteArray();
+ − }
+ − tmp_string=null;
+ − }
+ − catch(Return e){ return e.r; }
+ − }
+ − else if(gheader!=null){
+ − gheader.name=null;
+ − }
+ − this.mode = COMMENT;
+ − case COMMENT:
+ − if ((flags & 0x1000)!=0) {
+ − try {
+ − r=readString(r, f);
+ − if(gheader!=null){
+ − gheader.comment=tmp_string.toByteArray();
+ − }
+ − tmp_string=null;
+ − }
+ − catch(Return e){ return e.r; }
+ − }
+ − else if(gheader!=null){
+ − gheader.comment=null;
+ − }
+ − this.mode = HCRC;
+ − case HCRC:
+ − if ((flags & 0x0200)!=0) {
+ − try { r=readBytes(2, r, f); }
+ − catch(Return e){ return e.r; }
+ − if(gheader!=null){
+ − gheader.hcrc=(int)(this.need&0xffff);
+ − }
+ − if(this.need != (z.adler.getValue()&0xffffL)){
+ − this.mode = BAD;
+ − z.msg = "header crc mismatch";
+ − this.marker = 5; // can't try inflateSync
+ − break;
+ − }
+ − }
+ − z.adler = new CRC32();
+ −
+ − this.mode = BLOCKS;
+ − break;
+ − default:
+ − return Z_STREAM_ERROR;
+ − }
+ − }
+ − }
+ −
+ − int inflateSetDictionary(byte[] dictionary, int dictLength){
+ − if(z==null || (this.mode != DICT0 && this.wrap != 0)){
+ − return Z_STREAM_ERROR;
+ − }
+ −
+ − int index=0;
+ − int length = dictLength;
+ −
+ − if(this.mode==DICT0){
+ − long adler_need=z.adler.getValue();
+ − z.adler.reset();
+ − z.adler.update(dictionary, 0, dictLength);
+ − if(z.adler.getValue()!=adler_need){
+ − return Z_DATA_ERROR;
+ − }
+ − }
+ −
+ − z.adler.reset();
+ −
+ − if(length >= (1<<this.wbits)){
+ − length = (1<<this.wbits)-1;
+ − index=dictLength - length;
+ − }
+ − this.blocks.set_dictionary(dictionary, index, length);
+ − this.mode = BLOCKS;
+ − return Z_OK;
+ − }
+ −
+ − static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
+ −
+ − int inflateSync(){
+ − int n; // number of bytes to look at
+ − int p; // pointer to bytes
+ − int m; // number of marker bytes found in a row
+ − long r, w; // temporaries to save total_in and total_out
+ −
+ − // set up
+ − if(z == null)
+ − return Z_STREAM_ERROR;
+ − if(this.mode != BAD){
+ − this.mode = BAD;
+ − this.marker = 0;
+ − }
+ − if((n=z.avail_in)==0)
+ − return Z_BUF_ERROR;
+ −
+ − p=z.next_in_index;
+ − m=this.marker;
+ − // search
+ − while (n!=0 && m < 4){
+ − if(z.next_in[p] == mark[m]){
+ − m++;
+ − }
+ − else if(z.next_in[p]!=0){
+ − m = 0;
+ − }
+ − else{
+ − m = 4 - m;
+ − }
+ − p++; n--;
+ − }
+ −
+ − // restore
+ − z.total_in += p-z.next_in_index;
+ − z.next_in_index = p;
+ − z.avail_in = n;
+ − this.marker = m;
+ −
+ − // return no joy or set up to restart on a new block
+ − if(m != 4){
+ − return Z_DATA_ERROR;
+ − }
+ − r=z.total_in; w=z.total_out;
+ − inflateReset();
+ − z.total_in=r; z.total_out = w;
+ − this.mode = BLOCKS;
+ −
+ − return Z_OK;
+ − }
+ −
+ − // Returns true if inflate is currently at the end of a block generated
+ − // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ − // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ − // but removes the length bytes of the resulting empty stored block. When
+ − // decompressing, PPP checks that at the end of input packet, inflate is
+ − // waiting for these length bytes.
+ − int inflateSyncPoint(){
+ − if(z == null || this.blocks == null)
+ − return Z_STREAM_ERROR;
+ − return this.blocks.sync_point();
+ − }
+ −
+ − private int readBytes(int n, int r, int f) throws Return{
+ − if(need_bytes == -1){
+ − need_bytes=n;
+ − this.need=0;
+ − }
+ − while(need_bytes>0){
+ − if(z.avail_in==0){ throw new Return(r); }; r=f;
+ − z.avail_in--; z.total_in++;
+ − this.need = this.need |
+ − ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8));
+ − need_bytes--;
+ − }
+ − if(n==2){
+ − this.need&=0xffffL;
+ − }
+ − else if(n==4) {
+ − this.need&=0xffffffffL;
+ − }
+ − need_bytes=-1;
+ − return r;
+ − }
+ − class Return extends Exception{
+ − int r;
+ − Return(int r){this.r=r; }
+ − }
+ −
+ − private java.io.ByteArrayOutputStream tmp_string = null;
+ − private int readString(int r, int f) throws Return{
+ − if(tmp_string == null){
+ − tmp_string=new java.io.ByteArrayOutputStream();
+ − }
+ − int b=0;
+ − do {
+ − if(z.avail_in==0){ throw new Return(r); }; r=f;
+ − z.avail_in--; z.total_in++;
+ − b = z.next_in[z.next_in_index];
+ − if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1);
+ − z.adler.update(z.next_in, z.next_in_index, 1);
+ − z.next_in_index++;
+ − }while(b!=0);
+ − return r;
+ − }
+ −
+ − private int readBytes(int r, int f) throws Return{
+ − if(tmp_string == null){
+ − tmp_string=new java.io.ByteArrayOutputStream();
+ − }
+ − int b=0;
+ − while(this.need>0){
+ − if(z.avail_in==0){ throw new Return(r); }; r=f;
+ − z.avail_in--; z.total_in++;
+ − b = z.next_in[z.next_in_index];
+ − tmp_string.write(z.next_in, z.next_in_index, 1);
+ − z.adler.update(z.next_in, z.next_in_index, 1);
+ − z.next_in_index++;
+ − this.need--;
+ − }
+ − return r;
+ − }
+ −
+ − private void checksum(int n, long v){
+ − for(int i=0; i<n; i++){
+ − crcbuf[i]=(byte)(v&0xff);
+ − v>>=8;
+ − }
+ − z.adler.update(crcbuf, 0, n);
+ − }
+ −
+ − public GZIPHeader getGZIPHeader(){
+ − return gheader;
+ − }
+ −
+ − boolean inParsingHeader(){
+ − switch(mode){
+ − case HEAD:
+ − case DICT4:
+ − case DICT3:
+ − case DICT2:
+ − case DICT1:
+ − case FLAGS:
+ − case TIME:
+ − case OS:
+ − case EXLEN:
+ − case EXTRA:
+ − case NAME:
+ − case COMMENT:
+ − case HCRC:
+ − return true;
+ − default:
+ − return false;
+ − }
+ − }
+ − }