/*
* JLibs: Common Utilities for Java
* Copyright (C) 2009 Santhosh Kumar T <santhosh.tekuri@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*/
package jlibs.nio.http.msg.parser;
import jlibs.nio.http.msg.Message;
import jlibs.nio.http.msg.Response;
import jlibs.nio.http.msg.Status;
import java.nio.ByteBuffer;
import static jlibs.nio.http.util.USAscii.*;
/**
* @author Santhosh Kumar Tekuri
*/
public class ResponseParser extends MessageParser{
private static final int VERSION = 0;
private static final int STATUS = 1;
private static final int REASON = 2;
private static final int HEADERS = 3;
private int step = VERSION;
private int statusCode;
private int digitCount;
@Override
public boolean parse(ByteBuffer buffer, boolean eof){
char ch;
switch(step){
case VERSION:
if(parseVersion(buffer)){
ch = (char)buffer.get();
if(ch!=SP)
throw Status.BAD_GATEWAY.with("Bad Version");
step = STATUS;
if(!buffer.hasRemaining())
return false;
}
case STATUS:
while(buffer.hasRemaining()){
ch = (char)buffer.get();
if(digitCount==3){
if(ch!=SP)
throw Status.BAD_GATEWAY.with("Bad Status");
step = REASON;
if(!buffer.hasRemaining())
return false;
break;
}
if(!DIGIT[ch])
throw Status.BAD_GATEWAY.with("Bad Status");
++digitCount;
statusCode = statusCode*10 + (ch-'0');
}
case REASON:
while(buffer.hasRemaining()){
ch = (char)buffer.get();
if(ch==CR){
if(buffer.hasRemaining()){
ch = (char)buffer.get();
if(ch!=LF)
throw Status.BAD_GATEWAY.with("Bad EOL");
response.status = Status.valueOf(statusCode, builder);
builder.setLength(0);
step = HEADERS;
break;
}
}else if(ch==LF){
response.status = Status.valueOf(statusCode, builder);
builder.setLength(0);
step = HEADERS;
break;
}else
builder.append(ch);
}
case HEADERS:
return super.parse(buffer, eof);
}
return false;
}
private Response response;
public void reset(Message response){
super.reset(response);
this.response = (Response)response;
step = VERSION;
statusCode = 0;
digitCount = 0;
}
}