package co.nstant.in.cbor.decoder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import co.nstant.in.cbor.CborDecoder;
import co.nstant.in.cbor.CborException;
import co.nstant.in.cbor.model.ByteString;
import co.nstant.in.cbor.model.DataItem;
import co.nstant.in.cbor.model.MajorType;
import co.nstant.in.cbor.model.Special;

public class ByteStringDecoder extends AbstractDecoder<ByteString> {

    public ByteStringDecoder(CborDecoder decoder, InputStream inputStream) {
        super(decoder, inputStream);
    }

    @Override
    public ByteString decode(int initialByte) throws CborException {
        long length = getLength(initialByte);
        if (length == INFINITY) {
            if (decoder.isAutoDecodeInfinitiveByteStrings()) {
                return decodeInfinitiveLength();
            } else {
                ByteString byteString = new ByteString(null);
                byteString.setChunked(true);
                return byteString;
            }
        } else {
            return decodeFixedLength(length);
        }
    }

    private ByteString decodeInfinitiveLength() throws CborException {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        DataItem dataItem;
        for (;;) {
            dataItem = decoder.decodeNext();
            MajorType majorType = dataItem.getMajorType();
            if (Special.BREAK.equals(dataItem)) {
                break;
            } else if (majorType == MajorType.BYTE_STRING) {
                ByteString byteString = (ByteString) dataItem;
                try {
                    bytes.write(byteString.getBytes());
                } catch (IOException ioException) {
                    throw new CborException(ioException);
                }
            } else {
                throw new CborException("Unexpected major type "
                                + majorType);
            }
        }
        return new ByteString(bytes.toByteArray());
    }

    private ByteString decodeFixedLength(long length) throws CborException {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream((int) length);
        for (long i = 0; i < length; i++) {
            bytes.write(nextSymbol());
        }
        return new ByteString(bytes.toByteArray());
    }

}

@@ -1597,70 +1597,169 @@
     
-try %7B%0A                    bytes.write(byteString.getBytes());%0A
+byte%5B%5D byteArray = byteString.getBytes();%0A                if (byteArray != null) %7B%0A                    try %7B%0A                        bytes.write(byteArray);%0A    
     
@@ -1818,32 +1818,36 @@
                 
+    
 throw new CborEx
@@ -1868,16 +1868,38 @@
 ption);%0A
+                    %7D%0A
         
@@ -1994,28 +1994,16 @@
  type %22%0A
-            
         

Fix NPE found by Coverity.