📄 webserver.cpp
字号:
CProgressImage::~CProgressImage(){ delete [] m_gap_buf; delete [] m_ColorLine;}void CProgressImage::ReallocGapBuffer(){ int size = m_file->m_Encoder.m_gap_status.Size() / (2 * sizeof(uint64)); if ( size == m_gap_alloc_size ) { return; } if ( (size > m_gap_alloc_size) || (size < m_gap_alloc_size/2) ) { m_gap_buf_size = m_gap_alloc_size = size; delete [] m_gap_buf; m_gap_buf = new Gap_Struct[m_gap_alloc_size]; } else { m_gap_buf_size = size; }}void CProgressImage::InitSortedGaps(){ ReallocGapBuffer(); const uint64 *gap_info = (const uint64 *)m_file->m_Encoder.m_gap_status.Buffer(); m_gap_buf_size = m_file->m_Encoder.m_gap_status.Size() / (2 * sizeof(uint64)); //memcpy(m_gap_buf, gap_info, m_gap_buf_size*2*sizeof(uint32)); for (int j = 0; j < m_gap_buf_size;j++) { uint64 gap_start = ENDIAN_NTOHLL(gap_info[2*j]); uint64 gap_end = ENDIAN_NTOHLL(gap_info[2*j+1]); m_gap_buf[j].start = gap_start; m_gap_buf[j].end = gap_end; } qsort(m_gap_buf, m_gap_buf_size, 2*sizeof(uint64), compare_gaps);}void CProgressImage::CreateSpan(){ // Step 1: sort gaps list in accending order InitSortedGaps(); // allocate for worst case ! int color_gaps_alloc = 2 * (2*m_gap_buf_size + m_file->lFileSize / PARTSIZE + 1); Color_Gap_Struct *colored_gaps = new Color_Gap_Struct[color_gaps_alloc]; // Step 2: combine gap and part status information const unsigned char *part_info = m_file->m_Encoder.m_part_status.Buffer(); // Init first item to dummy info, so we will always have "previous" item int colored_gaps_size = 0; colored_gaps[0].start = 0; colored_gaps[0].end = 0; colored_gaps[0].color = 0xffffffff; for (int j = 0; j < m_gap_buf_size;j++) { uint64 gap_start = m_gap_buf[j].start; uint64 gap_end = m_gap_buf[j].end; uint32 start = gap_start / PARTSIZE; uint32 end = (gap_end / PARTSIZE) + 1; for (uint32 i = start; i < end; i++) { COLORREF color = RGB(255, 0, 0); if ( part_info[i] ) { int blue = 210 - ( 22 * ( part_info[i] - 1 ) ); color = RGB( 0, ( blue < 0 ? 0 : blue ), 255 ); } uint32 fill_gap_begin = ( (i == start) ? gap_start: PARTSIZE * i ); uint32 fill_gap_end = ( (i == (end - 1)) ? gap_end : PARTSIZE * ( i + 1 ) ); wxASSERT(colored_gaps_size < color_gaps_alloc); if ( (colored_gaps[colored_gaps_size].end == fill_gap_begin) && (colored_gaps[colored_gaps_size].color == color) ) { colored_gaps[colored_gaps_size].end = fill_gap_end; } else { colored_gaps_size++; colored_gaps[colored_gaps_size].start = fill_gap_begin; colored_gaps[colored_gaps_size].end = fill_gap_end; colored_gaps[colored_gaps_size].color = color; } } } // // Now line rendering for(int i = 0; i < m_width; ++i) { m_ColorLine[i] = 0x0; } if (m_file->lFileSize < (uint32)m_width) { // // if file is that small, draw it in single step // if (m_file->m_ReqParts.size()) { for(int i = 0; i < m_width; ++i) { m_ColorLine[i] = RGB(255, 208, 0); } } else if ( colored_gaps_size ) { for(int i = 0; i < m_width; ++i) { m_ColorLine[i] = colored_gaps[0].color; } } } else { uint32 factor = m_file->lFileSize / m_width; for(int i = 1; i <= colored_gaps_size;i++) { uint32 start = colored_gaps[i].start / factor; uint32 end = colored_gaps[i].end / factor; for(uint32 j = start; j < end; j++) { m_ColorLine[j] = colored_gaps[i].color; } } // overwrite requested parts for(uint32 i = 0; i < m_file->m_ReqParts.size(); i++) { uint32 start = m_file->m_ReqParts[i].start / factor; uint32 end = m_file->m_ReqParts[i].end / factor; for(uint32 j = start; j < end; j++) { m_ColorLine[j] = RGB(255, 208, 0); } } } delete [] colored_gaps;}int CProgressImage::compare_gaps(const void *g1, const void *g2){ return ((const Gap_Struct *)g1)->start - ((const Gap_Struct *)g2)->start;}#ifdef WITH_LIBPNGCDynPngImage::CDynPngImage(int w, int h) : CAnyImage(w, h){ // // Allocate array of "row pointers" - libpng need it in this form // Fill it also with the image data // m_img_data = new png_byte[3*m_width*m_height]; memset(m_img_data, 0, 3*m_width*m_height); m_row_ptrs = new png_bytep [m_height]; for (int i = 0; i < m_height;i++) { m_row_ptrs[i] = &m_img_data[3*m_width*i]; } }CDynPngImage::~CDynPngImage(){ delete [] m_row_ptrs; delete [] m_img_data;}void CDynPngImage::png_write_fn(png_structp png_ptr, png_bytep data, png_size_t length){ CDynPngImage *This = (CDynPngImage *)png_get_io_ptr(png_ptr); wxASSERT((png_size_t)(This->m_size + length) <= (png_size_t)This->m_alloc_size); memcpy(This->m_data + This->m_size, data, length); This->m_size += length;}unsigned char *CDynPngImage::RequestData(int &size){ // write png into buffer png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop info_ptr = png_create_info_struct(png_ptr); png_set_IHDR(png_ptr, info_ptr, m_width, m_height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_write_fn(png_ptr, this, png_write_fn, 0); m_size = 0; png_write_info(png_ptr, info_ptr); png_write_image(png_ptr, (png_bytep *)m_row_ptrs); png_write_end(png_ptr, 0); png_destroy_write_struct(&png_ptr, &info_ptr); return CAnyImage::RequestData(size);}CDynProgressImage::CDynProgressImage(int width, int height, wxString &tmpl, DownloadFile *file) : CAnyImage(width, height), CProgressImage(width, height, tmpl, file), CDynPngImage(width, height), m_modifiers(height){ m_name = wxT("dyn_") + m_file->sFileHash + wxT(".png");}CDynProgressImage::~CDynProgressImage(){}wxString CDynProgressImage::GetHTML(){ // template contain %s (name) %d (width) return (CFormat(m_template) % m_name % m_width).GetString();} void CDynProgressImage::DrawImage(){ CreateSpan(); for(int i = 0; i < m_height; i++) { memset(m_row_ptrs[i], 0, 3*m_width); } for(int i = 0; i < m_height/2; i++) { png_bytep u_row = m_row_ptrs[i]; png_bytep d_row = m_row_ptrs[m_height-i-1]; for(int j = 0; j < m_width; j++) { set_rgb_color_val(u_row+3*j, m_ColorLine[j], m_modifiers[i]); set_rgb_color_val(d_row+3*j, m_ColorLine[j], m_modifiers[i]); } }}unsigned char *CDynProgressImage::RequestData(int &size){ // create new one DrawImage(); return CDynPngImage::RequestData(size);}#elseCDynProgressImage::CDynProgressImage(int width, int height, wxString &tmpl, DownloadFile *file) : CAnyImage(width, height), CProgressImage(width, height, tmpl, file){ m_name = wxT("dyn_") + m_file->sFileHash + wxT(".png"); }wxString CDynProgressImage::GetHTML(){ static wxChar *progresscolor[12] = { wxT("transparent.gif"), wxT("black.gif"), wxT("yellow.gif"), wxT("red.gif"), wxT("blue1.gif"), wxT("blue2.gif"), wxT("blue3.gif"), wxT("blue4.gif"), wxT("blue5.gif"), wxT("blue6.gif"), wxT("green.gif"), wxT("greenpercent.gif") }; CreateSpan(); wxString str; uint32 lastcolor = m_ColorLine[0]; int lastindex = 0; for(int i = 0; i < m_width; i++) { if ( (lastcolor != m_ColorLine[i]) || (i == (m_width - 1)) ) { int color_idx = -1; if ( lastcolor & RGB(0, 0, 0xff) ) { // blue int green = (lastcolor >> 8) & 0xff; // reverse calculation: green = 210 - ( 22 * ( part_info[i] - 1 ) ) wxASSERT( !green || (green < 211) ); color_idx = (green) ? (210 - green) / 22 + 1 : 11; // now calculate it same way as PartFile did color_idx = (color_idx > 10) ? 9 : (4 + color_idx / 2); } else { if ( lastcolor & RGB(0, 0xff, 0) ) { // yellow color_idx = 2; } else { if ( lastcolor & RGB(0xff, 0, 0) ) { // red color_idx = 3; } else { color_idx = 1; } } } str += (CFormat(m_template) % progresscolor[color_idx] % (i - lastindex)).GetString(); lastindex = i; lastcolor = m_ColorLine[i]; } } return str;}#endifCStatsData::CStatsData(int size){ m_size = size; m_data = new uint32[size]; m_max_value = 0; // // initial situation: all data is 0's // memset(m_data, 0, m_size*sizeof(int)); m_start_index = m_curr_index = 0; m_end_index = size - 1;}CStatsData::~CStatsData(){ delete [] m_data;}uint32 CStatsData::GetFirst(){ m_curr_index = m_start_index; return m_data[m_curr_index];}uint32 CStatsData::GetNext(){ m_curr_index++; m_curr_index %= m_size; return m_data[m_curr_index];}void CStatsData::PushSample(uint32 sample){ m_start_index = (m_start_index + 1) % m_size; m_end_index = (m_end_index + 1) % m_size; m_data[m_start_index] = sample; if ( m_max_value < sample ) { m_max_value = sample; }}CStatsCollection::CStatsCollection(int size, CamulewebApp *iface){ m_down_speed = new CStatsData(size); m_up_speed = new CStatsData(size); m_conn_number = new CStatsData(size); m_kad_count = new CStatsData(size); m_iface = iface; m_LastTimeStamp = 0.0; m_size = size;}CStatsCollection::~CStatsCollection(){ delete m_down_speed; delete m_up_speed; delete m_conn_number;}void CStatsCollection::ReQuery(){ CECPacket request(EC_OP_GET_STATSGRAPHS); request.AddTag(CECTag(EC_TAG_STATSGRAPH_WIDTH, (uint16)m_size)); uint16 m_nGraphScale = 1; request.AddTag(CECTag(EC_TAG_STATSGRAPH_SCALE, m_nGraphScale)); if (m_LastTimeStamp > 0.0) { request.AddTag(CECTag(EC_TAG_STATSGRAPH_LAST, m_LastTimeStamp)); } const CECPacket *response = m_iface->SendRecvMsg_v2(&request); m_LastTimeStamp = response->GetTagByNameSafe(EC_TAG_STATSGRAPH_LAST)->GetDoubleData(); const CECTag *dataTag = response->GetTagByName(EC_TAG_STATSGRAPH_DATA); const uint32 *data = (const uint32 *)dataTag->GetTagData(); unsigned int count = dataTag->GetTagDataLen() / sizeof(uint32); for (unsigned int i = 0; i < count; i += 4) { m_down_speed->PushSample(ENDIAN_NTOHL(data[i+0])); m_up_speed->PushSample(ENDIAN_NTOHL(data[i+1])); m_conn_number->PushSample(ENDIAN_NTOHL(data[i+2])); m_kad_count->PushSample(ENDIAN_NTOHL(data[i+3])); }}//// Dynamically generated statistic images//#ifdef WITH_LIBPNGCDynStatisticImage::CDynStatisticImage(int height, bool scale1024, CStatsData *data) : CAnyImage(data->Size(), height), CDynPngImage(data->Size(), height){ m_data = data; m_scale1024 = scale1024; // actual name doesn't matter, just make it unique m_name = wxString::Format(wxT("dyn_%ld_stat.png"), (unsigned long int) data); m_num_font_w_size = 8; m_num_font_h_size = 16; // leave enough space for 4 digit number int img_delta = m_num_font_w_size / 4; m_left_margin = 4*(m_num_font_w_size + img_delta) + img_delta; // leave enough space for number height m_bottom_margin = m_num_font_h_size; m_y_axis_size = m_height - m_bottom_margin; // allocate storage for background. Using 1 chunk to speed up // the rendering m_background = new png_byte[m_width*m_height*3]; m_row_bg_ptrs = new png_bytep[m_height]; for(int i = 0; i < m_height; i++) { m_row_bg_ptrs[i] = &m_background[i*m_width*3]; } // // Prepare background // static const COLORREF bg_color = RGB(0x00, 0x00, 0x40); for(int i = 0; i < m_height; i++) { png_bytep u_row = m_row_bg_ptrs[i]; for(int j = 0; j < m_width; j++) { set_rgb_color_val(u_row+3*j, bg_color, 0); } } // // draw axis // static const COLORREF axis_color = RGB(0xff, 0xff, 0xff); // Y for(int i = m_bottom_margin; i < m_y_axis_size; i++) { png_bytep u_row = m_row_bg_ptrs[i]; set_rgb_color_val(u_row+3*(m_left_margin + 0), axis_color, 0); set_rgb_color_val(u_row+3*(m_left_margin + 1), axis_color, 0); } // X for(int j = m_left_margin; j < m_width; j++) { set_rgb_color_val(m_row_bg_ptrs[m_y_axis_size - 0]+3*j, axis_color, 0); set_rgb_color_val(m_row_bg_ptrs[m_y_axis_size - 1]+3*j, axis_color, 0); } // horisontal grid int v_grid_size = m_y_axis_size / 4; for(int i = m_y_axis_size - v_grid_size; i >= v_grid_size; i -= v_grid_size) { png_bytep u_row = m_row_bg_ptrs[i]; for(int j = m_left_margin; j < m_width; j++) { if ( (j % 10) < 5 ) { set_rgb_color_val(u_row+3*j, axis_color, 0); } } } // // Pre-create masks for digits // for(int i = 0; i < 10; i++) { m_digits[i] = new CNumImageMask(i, m_num_font_w_size, m_num_font_h_size); }}CDynStatisticImage::~CDynStatisticImage(){ delete [] m_row_bg_ptrs; delete [] m_background; for(int i = 0; i < 10; i++) { delete m_digits[i]; }}void CDynStatisticImage::DrawImage(){ // copy background first memcpy(m_img_data, m_background, m_width*m_height*3); // // Now graph itself // static const COLORREF graph_color = RGB(0xff, 0x00, 0x00); int maxval = m_data->Max(); if ( m_scale1024 ) { if ( maxval > 1024 ) { maxval /= 1024; } else { maxval = 1; } } // // Check if we need to scale data up or down // int m_scale_up = 1, m_scale_down = 1; if ( maxval >= (m_height - m_bottom_margin) ) { m_scale_down = 1 + (maxval / (m_y_axis_size - 10)); } // if maximum value is 1/5 or less of graph height - scale it UP, to make 2/3 if ( maxval && (maxval < (m_y_axis_size / 5)) ) { m_scale_up = (2*m_y_axis_size / 3) / maxval; } // // draw axis scale // int img_delta = m_num_font_w_size / 4; // Number "0" is always there m_digits[0]->Apply(m_row_ptrs, 3*img_delta+2*m_num_font_w_size, m_y_axis_size-m_num_font_h_size-5); // // When data is scaled down, axis are scaled UP and viceversa int y_axis_max = m_y_axis_size; if ( m_scale_down != 1 ) { y_axis_max *= m_scale_down;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -