// Path: src/main/java/jresp/RespDecoder.java
// public class RespDecoder {
// 
//     private SimpleStrState simpleStrDecoder = new SimpleStrState();
//     private ErrState errDecoder = new ErrState();
//     private IntState intDecoder = new IntState();
//     private BulkStrState bulkStrDecoder;
// 
//     private State state = null;
// 
//     RespDecoder() {
//         bulkStrDecoder = new BulkStrState(this);
//     }
// 
//     protected void decode(ByteBuffer in, Consumer<RespType> out) {
//         while (true) {
//             int availableBytes = in.remaining();
//             if (availableBytes == 0) {
//                 //
//                 // We need more bytes
//                 //
//                 break;
//             }
// 
//             if (state == null) {
//                 //
//                 // There is no current state, so read the next byte
//                 //
//                 char nextChar = (char) in.get();
//                 state = nextState(nextChar);
//             }
//             if (state.decode(in)) {
//                 out.accept(state.finish());
//                 state = null;
//             } else {
//                 //
//                 // We need more bytes
//                 //
//                 break;
//             }
//         }
//     }
// 
//     public State nextState(char token) {
//         switch (token) {
//             case '+':
//                 return simpleStrDecoder.reset();
//             case '-':
//                 return errDecoder.reset();
//             case ':':
//                 return intDecoder.reset();
//             case '$':
//                 return bulkStrDecoder.reset();
//             case '*':
//                 return new AryState(this);
//             default:
//                 throw new IllegalStateException(String.format("Unknown token %s", token));
//         }
//     }
// 
//     public IntState intDecoder() {
//         return (IntState)intDecoder.reset();
//     }
// }
// 
// Path: src/main/java/jresp/protocol/Ary.java
// public class Ary implements RespType {
//     private List<RespType> payload;
// 
//     public Ary(List<RespType> payload) {
//         this.payload = payload;
//     }
// 
//     public Ary(RespType... payload) {
//         this.payload = Arrays.asList(payload);
//     }
// 
//     public String toString() {
//         return String.format("%s[%s]", getClass().getName(), payload);
//     }
// 
//     @Override
//     public void writeBytes(Deque<ByteBuffer> out) {
//         byte[] header = Resp.longToByteArray(payload.size());
//         int size = 1 + header.length + 2;
//         ByteBuffer o = Resp.buffer(out, size);
//         o.put((byte)'*');
//         o.put(header);
//         o.put(Resp.CRLF);
//         payload.stream().forEach(x -> x.writeBytes(out));
//     }
// 
//     public List<RespType> raw() {
//         return payload;
//     }
// 
//     @Override
//     public Object unwrap() {
//         return payload.stream().map(RespType::unwrap).collect(Collectors.toList());
//     }
// 
//     @Override
//     public int hashCode() {
//         return payload.hashCode();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o instanceof Ary) {
//             Ary a = (Ary)o;
//             return payload.equals(a.payload);
//         } else {
//             return false;
//         }
//     }
// }
// 
// Path: src/main/java/jresp/protocol/RespType.java
// public interface RespType {
//     /**
//      * Write the RESP form to the ByteBuf
//      */
//     void writeBytes(Deque<ByteBuffer> out);
// 
//     /**
//      * Return the high-level Java equivalent.
//      */
//     Object unwrap();
// }


import jresp.RespDecoder;
import jresp.protocol.Ary;
import jresp.protocol.RespType;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/*
 * Copyright 2015 Ben Ashford
 *
 * 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 jresp.state;



public class AryState implements State {
    private RespDecoder parent;

    private IntState intState;
    private Integer aryLength = null;
    private List<RespType> ary = null;
    private State nextState = null;

    public AryState(RespDecoder parent) {
        this.parent = parent;
        this.intState = parent.intDecoder();
    }

    @Override
    public boolean decode(ByteBuffer in) {
        while (true) {
            if (aryLength == null) {
                if (intState.decode(in)) {
                    aryLength = (int) intState.finishInt();
                    ary = new ArrayList<>(aryLength);
                    if (aryLength == 0) {
                        //
                        // This is an empty array, so there will be no "nextState", so let's short-cut proceedings here
                        //
// Path: src/main/java/jresp/RespDecoder.java
// public class RespDecoder {
// 
//     private SimpleStrState simpleStrDecoder = new SimpleStrState();
//     private ErrState errDecoder = new ErrState();
//     private IntState intDecoder = new IntState();
//     private BulkStrState bulkStrDecoder;
// 
//     private State state = null;
// 
//     RespDecoder() {
//         bulkStrDecoder = new BulkStrState(this);
//     }
// 
//     protected void decode(ByteBuffer in, Consumer<RespType> out) {
//         while (true) {
//             int availableBytes = in.remaining();
//             if (availableBytes == 0) {
//                 //
//                 // We need more bytes
//                 //
//                 break;
//             }
// 
//             if (state == null) {
//                 //
//                 // There is no current state, so read the next byte
//                 //
//                 char nextChar = (char) in.get();
//                 state = nextState(nextChar);
//             }
//             if (state.decode(in)) {
//                 out.accept(state.finish());
//                 state = null;
//             } else {
//                 //
//                 // We need more bytes
//                 //
//                 break;
//             }
//         }
//     }
// 
//     public State nextState(char token) {
//         switch (token) {
//             case '+':
//                 return simpleStrDecoder.reset();
//             case '-':
//                 return errDecoder.reset();
//             case ':':
//                 return intDecoder.reset();
//             case '$':
//                 return bulkStrDecoder.reset();
//             case '*':
//                 return new AryState(this);
//             default:
//                 throw new IllegalStateException(String.format("Unknown token %s", token));
//         }
//     }
// 
//     public IntState intDecoder() {
//         return (IntState)intDecoder.reset();
//     }
// }
// 
// Path: src/main/java/jresp/protocol/Ary.java
// public class Ary implements RespType {
//     private List<RespType> payload;
// 
//     public Ary(List<RespType> payload) {
//         this.payload = payload;
//     }
// 
//     public Ary(RespType... payload) {
//         this.payload = Arrays.asList(payload);
//     }
// 
//     public String toString() {
//         return String.format("%s[%s]", getClass().getName(), payload);
//     }
// 
//     @Override
//     public void writeBytes(Deque<ByteBuffer> out) {
//         byte[] header = Resp.longToByteArray(payload.size());
//         int size = 1 + header.length + 2;
//         ByteBuffer o = Resp.buffer(out, size);
//         o.put((byte)'*');
//         o.put(header);
//         o.put(Resp.CRLF);
//         payload.stream().forEach(x -> x.writeBytes(out));
//     }
// 
//     public List<RespType> raw() {
//         return payload;
//     }
// 
//     @Override
//     public Object unwrap() {
//         return payload.stream().map(RespType::unwrap).collect(Collectors.toList());
//     }
// 
//     @Override
//     public int hashCode() {
//         return payload.hashCode();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o instanceof Ary) {
//             Ary a = (Ary)o;
//             return payload.equals(a.payload);
//         } else {
//             return false;
//         }
//     }
// }
// 
// Path: src/main/java/jresp/protocol/RespType.java
// public interface RespType {
//     /**
//      * Write the RESP form to the ByteBuf
//      */
//     void writeBytes(Deque<ByteBuffer> out);
// 
//     /**
//      * Return the high-level Java equivalent.
//      */
//     Object unwrap();
// }


// Path: src/main/java/jresp/state/AryState.java
import jresp.RespDecoder;
import jresp.protocol.Ary;
import jresp.protocol.RespType;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/*
 * Copyright 2015 Ben Ashford
 *
 * 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 jresp.state;



public class AryState implements State {
    private RespDecoder parent;

    private IntState intState;
    private Integer aryLength = null;
    private List<RespType> ary = null;
    private State nextState = null;

    public AryState(RespDecoder parent) {
        this.parent = parent;
        this.intState = parent.intDecoder();
    }

    @Override
    public boolean decode(ByteBuffer in) {
        while (true) {
            if (aryLength == null) {
                if (intState.decode(in)) {
                    aryLength = (int) intState.finishInt();
                    ary = new ArrayList<>(aryLength);
                    if (aryLength == 0) {
                        //
                        // This is an empty array, so there will be no "nextState", so let's short-cut proceedings here
                        //
                        return true;