void Response::ProcessStatusLine( std::string const& line ) { const char* p = line.c_str(); // skip any leading space while( *p && *p == ' ' ) ++p; // get version while( *p && *p != ' ' ) m_VersionString += *p++; while( *p && *p == ' ' ) ++p; // get status code std::string status; while( *p && *p != ' ' ) status += *p++; while( *p && *p == ' ' ) ++p; // rest of line is reason while( *p ) m_Reason += *p++; m_Status = atoi( status.c_str() ); if( m_Status < 100 || m_Status > 999 ) throw Wobbly( "BadStatusLine (%s)", line.c_str() ); /* printf( "version: '%s'\n", m_VersionString.c_str() ); printf( "status: '%d'\n", m_Status ); printf( "reason: '%s'\n", m_Reason.c_str() ); */ if( m_VersionString == "HTTP:/1.0" ) m_Version = 10; else if( 0==m_VersionString.compare( 0,7,"HTTP/1." ) ) m_Version = 11; else throw Wobbly( "UnknownProtocol (%s)", m_VersionString.c_str() ); // TODO: support for HTTP/0.9 // OK, now we expect headers! m_State = HEADERS; m_HeaderAccum.clear(); }
void Connection::connect() { in_addr* addr = atoaddr( m_Host.c_str() ); if( !addr ) { std::cerr << m_Host.c_str() << std::endl; throw Wobbly( "Invalid network address" ); } sockaddr_in address; memset( (char*)&address, 0, sizeof(address) ); address.sin_family = AF_INET; address.sin_port = htons( m_Port ); address.sin_addr.s_addr = addr->s_addr; m_Sock = socket( AF_INET, SOCK_STREAM, 0 ); if( m_Sock < 0 ) BailOnSocketError( "socket()" ); // printf("Connecting to %s on port %d.\n",inet_ntoa(*addr), port); if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 ) BailOnSocketError( "connect()" ); }
SDLController::SDLController(int j_idx) : m_Ctrl(0) { m_Ctrl = SDL_GameControllerOpen(j_idx); if (!m_Ctrl) { throw Wobbly("Couldn't open controller: %s", SDL_GetError()); } //const char *name = SDL_GameControllerNameForIndex(j_idx); }
void Connection::pump() { if( m_Outstanding.empty() ) return; // no requests outstanding if (m_Sock < 0) { throw Wobbly("Pumping unconnected socket."); } //assert( m_Sock >0 ); // outstanding requests but no connection! if( !datawaiting( m_Sock ) ) return; // recv will block unsigned char buf[ 2048 ]; int a = recv( m_Sock, (char*)buf, sizeof(buf), 0 ); if( a<0 ) BailOnSocketError( "recv()" ); if( a== 0 ) { // connection has closed Response* r = m_Outstanding.front(); r->notifyconnectionclosed(); assert( r->completed() ); delete r; m_Outstanding.pop_front(); // any outstanding requests will be discarded close(); } else { int used = 0; while( used < a && !m_Outstanding.empty() ) { Response* r = m_Outstanding.front(); int u = r->pump( &buf[used], a-used ); // delete response once completed if( r->completed() ) { delete r; m_Outstanding.pop_front(); } used += u; } // NOTE: will lose bytes if response queue goes empty // (but server shouldn't be sending anything if we don't have // anything outstanding anyway) assert( used == a ); // all bytes should be used up by here. } }
void BailOnSocketError( const char* context ) { #ifdef WIN32 int e = WSAGetLastError(); const char* msg = GetWinsockErrorString( e ); #else const char* msg = strerror( errno ); #endif throw Wobbly( "%s: %s", context, msg ); }
// Connection has closed void Response::notifyconnectionclosed() { if( m_State == COMPLETE ) return; // eof can be valid... if( m_State == BODY && !m_Chunked && m_Length == -1 ) { Finish(); // we're all done! } else { throw Wobbly( "Connection closed unexpectedly" ); } }
void Connection::endheaders() { if( m_State != REQ_STARTED ) throw Wobbly( "Cannot send header" ); m_State = IDLE; m_Buffer.push_back( "" ); string msg; vector< string>::const_iterator it; for( it = m_Buffer.begin(); it != m_Buffer.end(); ++it ) msg += (*it) + "\r\n"; m_Buffer.clear(); // printf( "%s", msg.c_str() ); send( (const unsigned char*)msg.c_str(), msg.size() ); }
void Connection::putrequest( const char* method, const char* url ) { if( m_State != IDLE ) throw Wobbly( "Request already issued" ); m_State = REQ_STARTED; char req[ 512 ]; sprintf( req, "%s %s HTTP/1.1", method, url ); m_Buffer.push_back( req ); putheader( "Host", m_Host.c_str() ); // required for HTTP1.1 // don't want any fancy encodings please putheader("Accept-Encoding", "identity"); // Push a new response onto the queue Response *r = new Response( method, *this ); m_Outstanding.push_back( r ); }
// ac and av are commandline options passed along from main() // Commandline options override config file options. void ZigConfig::Init( int ac, char* av[] ) { // try to read in opts from file { std::string inname = JoinPath( ZigUserDir(), "options" ); std::ifstream in( inname.c_str() ); int linenum = 0; while( in.good() ) { std::string line; std::getline( in, line ); ++linenum; std::vector< std::string > opts; SplitLine( line, opts ); if( opts.empty() ) // ignore blank lines continue; ApplyOption( *this, opts ); } } // now apply commandline opts on top. int i=1; while( i<ac ) { std::vector< std::string > opt; if( av[i][0] != '-' ) throw Wobbly( "Syntax error: '%s'", av[i] ); opt.push_back( &av[i][1] ); ++i; // collect args for this option while( i<ac && av[i][0] != '-' ) { opt.push_back( av[i] ); ++i; } ApplyOption( *this, opt ); } }
void Connection::putheader( const char* header, const char* value ) { if( m_State != REQ_STARTED ) throw Wobbly( "putheader() failed" ); m_Buffer.push_back( string(header) + ": " + string( value ) ); }
void SavePNG( Img const& img, RGBx const* palette, const char* filename ) { assert(img.Format()==Img::INDEXED8BIT); // TODO: set error handler to capture error msg? FILE *fp = fopen(filename, "wb"); if (!fp) { throw Wobbly( "open failed: %s", strerror(errno) ); } png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)0,0,0 ); if (!png_ptr) { fclose(fp); throw Wobbly( "failed writing PNG (png_create_write() failed)" ); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { fclose(fp); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); throw Wobbly( "failed writing PNG (png_create_info_struct() failed)" ); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); throw Wobbly( "failed writing PNG" ); } png_init_io(png_ptr, fp); png_set_IHDR( png_ptr, info_ptr, img.W(), img.H(), 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); { png_color tmp_palette[256]; int i; for(i=0;i<256;++i) { tmp_palette[i].red = palette[i].r; tmp_palette[i].green = palette[i].g; tmp_palette[i].blue = palette[i].b; } png_set_PLTE( png_ptr, info_ptr, tmp_palette, 256 ); } //png_set_bKGD( png_ptr, info_ptr, 0 ); { png_bytep row_pointers[ img.H() ]; int y; for( y=0;y<img.H();++y) row_pointers[y] = (png_bytep)img.PtrConst(0,y); png_set_rows( png_ptr, info_ptr, row_pointers ); png_write_png(png_ptr, info_ptr, 0, NULL); } png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); }
void LoadPNG( Img& img, RGBx* palette, const char* filename ) { FILE *fp = fopen(filename, "rb"); if (!fp) throw Wobbly( "open failed: %s", strerror(errno) ); unsigned char header[8]; fread( header, 1, 8, fp ); bool is_png = !png_sig_cmp( header, 0, 8 ); if( !is_png ) { fclose(fp); throw Wobbly( "Not a PNG file." ); } png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL ); if( !png_ptr ) { fclose(fp); throw Wobbly( "png_create_read_struct() failed" ); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { fclose(fp); png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); throw Wobbly( "png_create_info_struct() failed" ); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { fclose(fp); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); throw Wobbly( "png_create_info_struct() failed" ); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); throw Wobbly( "error reading PNG" ); } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_uint_32 width; png_uint_32 height; int color_type; int bit_depth; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); if( color_type != PNG_COLOR_TYPE_PALETTE ) { throw Wobbly( "PNG does not have a palette" ); } if (bit_depth == 16) png_set_strip_16(png_ptr); if (bit_depth < 8) png_set_packing(png_ptr); // read in the image data Img tmp( Img::INDEXED8BIT, width, height ); png_bytep row_pointers[ tmp.H() ]; int y; for( y=0;y<tmp.H();++y) row_pointers[y] = (png_bytep)tmp.Ptr(0,y); png_read_image( png_ptr, row_pointers ); img.Copy(tmp); // now read in the palette png_colorp colours; int num_colours; png_get_PLTE(png_ptr, info_ptr, &colours, &num_colours); assert( num_colours <= 256 ); int i=0; while( i<num_colours ) { png_color c = colours[i]; palette[i] = RGBx( c.red, c.green, c.blue ); ++i; } // black out any missing colours while( i<=255 ) { palette[i] = RGBx(0,0,0); ++i; } png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); }