//在指定的行读一数据名称 char *Ini::ReadCaption(char *index, int lines, char* str, int size) { //__ENTER_FUNCTION char szTmp[512] ; memset( szTmp, 0, 512 ) ; sprintf( szTmp, "[%s][%s][%d]", m_strFileName, index, lines ) ; int n=FindIndex(index); //AssertEx( n != -1, szTmp ); //跳到指定行数 n=GotoNextLine(n); for(int i=0; i<lines; i++) { if( n<m_lDataLen ) n=GotoNextLine(n); } char* ret = ReadDataName(n); strncpy( str, ret, size ) ; return ret ; //__LEAVE_FUNCTION // return 0 ; }
//返回连续的行数 int Ini::GetContinueDataNum(char *index) { //__ENTER_FUNCTION int num=0; int n=FindIndex(index); n=GotoNextLine(n); while(1) { if( m_strData[n] == '\r' || m_strData[n] == EOF || m_strData[n] == -3 || m_strData[n] == ' ' || m_strData[n] == '/' || m_strData[n] == '\t' || m_strData[n] == '\n' ) { return num; } else { num++; n=GotoNextLine(n); if( n >= m_lDataLen ) return num; } } //__LEAVE_FUNCTION // return 0 ; }
/*================================================================ * 函数名: ReadInt * 参数: [in] (int index_name)当前索引名称 * [in] (int lines)指定的行 * 功能描述: 在指定的行读一整数 * 返回值: 成功则返回整形数据, 否则返0 ================================================================*/ int CIni::ReadInt(char *index_name, int lines) { int data_pos = FindIndex(index_name); //跳到指定行数 data_pos = GotoNextLine(data_pos); for (int i = 0; i < lines; i++) { if (data_pos < m_data_length) data_pos = GotoNextLine(data_pos); } //读数据 while (data_pos < m_data_length) { if (m_str_data[data_pos] == '=') { data_pos++; char *str = LRTrim(ReadText(data_pos)); int ret = atoi(str); free(str); return ret; } if (m_str_data[data_pos] == '\n') { return ERROR_DATA; } data_pos++; } return ERROR_DATA; }
/*================================================================ * 函数名: ReadText * 参数1: [in] (int index_name)当前索引名称 * 参数2: [in] (int lines)指定的行 * 参数3: [in|out] (const char *default)默认数值 * 功能描述: 在指定的行读一字符串 * 返回值: 成功则返回文本数据, 否则返回默认值 ================================================================*/ char *CIni::ReadText(char *index_name, int lines, const char *default_name) { int data_pos = FindIndex(index_name); if (ERROR_DATA_POS == data_pos) return (char *)default_name; // 跳到指定行数 data_pos = GotoNextLine(data_pos); for (int i = 0; i < lines; i++) { if (data_pos < m_data_length) data_pos = GotoNextLine(data_pos); } // 读数据 while (data_pos <= m_data_length) { if (m_str_data[data_pos] == '=') { data_pos++; return LRTrim(ReadText(data_pos)); } if (m_str_data[data_pos] == '\n') { return (char *)default_name; } data_pos++; } return (char *)default_name; }
/*================================================================ * 函数名: GetContinueDataNum * 参数: [in] (char *index_name)当前索引名称 * 功能描述: 返回连续的行数 * 返回值: 成功则返回连续的行数, 否则返0 ================================================================*/ int CIni::GetContinueDataNum(char *index_name) { int num = 0; int data_pos = FindIndex(index_name); data_pos = GotoNextLine(data_pos); while(1) { if (m_str_data[data_pos] == '\n' || m_str_data[data_pos] == EOF || m_str_data[data_pos] == ' ' || m_str_data[data_pos] == '/' || m_str_data[data_pos] == '[' || m_str_data[data_pos] == ' ' ) { return num; } else { num++; data_pos = GotoNextLine(data_pos); if (data_pos >= m_data_length) { return num; } } } return num; }
/*================================================================ * 函数名: ReadInt * 参数: [in] (int index_name)当前索引名称 * [in] (int lines)指定的行 * 功能描述: 在指定的行读一KEY名称 * 返回值: 成功则返回整形数据, 否则返0 ================================================================*/ char *CIni::ReadCaption(char *index_name, int lines) { int data_pos = FindIndex(index_name); if (ERROR_DATA_POS == data_pos) return ""; //跳到指定行数 data_pos = GotoNextLine(data_pos); for (int i = 0; i < lines; i++) { if (data_pos < m_data_length) { data_pos = GotoNextLine(data_pos); } } return ReadKeyName(data_pos); }
//在当前位置加入一个数据 bool Ini::AddData(int p, char *name, char *string) { //__ENTER_FUNCTION char *str; int len=(int)(strlen(string)); str=new char[len+256]; memset(str, 0, len+256); sprintf(str,"%s=%s\r\n",name,string); len=(int)(strlen(str)); p=GotoNextLine(p); //提行 m_strData = (char *)realloc(m_strData, m_lDataLen+len); //重新分配内存 char *temp=new char[m_lDataLen-p]; memcpy(temp, &m_strData[p], m_lDataLen-p); memcpy(&m_strData[p+len], temp, m_lDataLen-p); //把后面的搬到末尾 memcpy(&m_strData[p], str, len); m_lDataLen+=len; SAFE_DELETE_ARRAY( temp ); SAFE_DELETE_ARRAY( str ); return true; //__LEAVE_FUNCTION // return 0 ; }
//返回指定数据的位置 int Ini::FindData(int index, char *string) { //__ENTER_FUNCTION int p=index; //指针 while(1) { p=GotoNextLine(p); char *name=ReadDataName(p); if( strcmp(string, name)==0 ) { SAFE_DELETE_ARRAY( name ); return p; } if ( name[0] == '[' ) { SAFE_DELETE_ARRAY( name ); return -1; } SAFE_DELETE_ARRAY( name ); if( p>=m_lDataLen ) return -1; } return -1; //__LEAVE_FUNCTION // return 0 ; }
//在指定位置读一字符串 char *Ini::ReadText(int p) { //__ENTER_FUNCTION char chr; char *Ret; int n=p, m=0; int LineNum = GotoNextLine(p) - p + 1; Ret=(char*)m_szValue;//new char[LineNum]; memset(Ret, 0, LineNum); for(int i=0; i<m_lDataLen-p; i++) { chr = m_strData[n]; //结束 if( chr == ';' || chr == '\r' || chr == '\t' || chr == ']' ) { //ShowMessage(Ret); return Ret; } Ret[m]=chr; m++; n++; } return Ret; //__LEAVE_FUNCTION // return 0 ; }
//在指定的行读一字符串 char *Ini::ReadText(char *index, int lines, char* str, int size) { //__ENTER_FUNCTION char szTmp[512] ; memset( szTmp, 0, 512 ) ; sprintf( szTmp, "[%s][%s][%d]", m_strFileName, index, lines ) ; int n=FindIndex(index); //AssertEx( n != -1, szTmp ); //跳到指定行数 n=GotoNextLine(n); for(int i=0; i<lines; i++) { if( n<m_lDataLen ) n=GotoNextLine(n); } //读数据 while( n<=m_lDataLen ) { if( m_strData[n] == '=' ) { n++; char* ret = ReadText(n); strncpy( str, ret, size ) ; return ret ; } if( m_strData[n] == '\r' ) { return NULL; } n++; } return NULL; //__LEAVE_FUNCTION // return 0 ; }
//在指定的行读一整数 int Ini::Readint(char *index, int lines) { //__ENTER_FUNCTION char szTmp[512] ; memset( szTmp, 0, 512 ) ; sprintf( szTmp, "[%s][%s][%d]", m_strFileName, index, lines ) ; int n=FindIndex(index); //AssertEx( n != -1, szTmp ); //跳到指定行数 n=GotoNextLine(n); for(int i=0; i<lines; i++) { if( n<m_lDataLen ) n=GotoNextLine(n); } //读数据 while( n<m_lDataLen ) { if( m_strData[n] == '=' ) { n++; char *str=ReadText(n); int ret=atoi(str); // free(str); return ret; } if( m_strData[n] == '\r' ) { return ERROR_DATA; } n++; } return ERROR_DATA; //__LEAVE_FUNCTION // return 0 ; }
/*================================================================ * 函数名: GotoLastLine * 参数: [in] (int index_name)当前索引名称 * 功能描述: 把指针移动到本INDEX的最后一行 * 返回值: 成功则返回true, 否则返false ================================================================*/ int CIni::GotoLastLine(char *index_name) { int data_pos = FindIndex(index_name); data_pos = GotoNextLine(data_pos); while(1) { if (m_str_data[data_pos] == '\n' || m_str_data[data_pos] == EOF || m_str_data[data_pos] == ' ' || m_str_data[data_pos] == '/' || m_str_data[data_pos] == ' ' ) { return data_pos; } else { data_pos = GotoNextLine(data_pos); if (data_pos >= m_data_length) { return data_pos; } } } }
/*================================================================ * 函数名: FindData * 参数: [in] (int index)文件索引的当前位置 * [in] (char *string)文件KEY的名称 * 功能描述: 返回指定数据的位置 * 返回值: 成功则返回指定数据的当前位置, 否则返回-10 ================================================================*/ int CIni::FindData(int index, char *string) { int data_pos = index; //指针 while(1) { data_pos = GotoNextLine(data_pos); char *name = ReadKeyName(data_pos); if (strcmp(string, name) == 0) { SAFE_FREE(name); return data_pos; } SAFE_FREE( name ); if (data_pos >= m_data_length) return ERROR_DATA_POS; } return ERROR_DATA_POS; }
/*================================================================ * 函数名: AddData * 参数: [in] (int pos)当前文件位置 * [in] (char *key_name)KEY名称 * [in] (char *value_name)VALUE名称 * 功能描述: 在当前位置加入一个数据 * 返回值: 成功则返回true, 否则返false ================================================================*/ bool CIni::AddData(int pos, char *key_name, char *value_name) { char *str = NULL; int len = strlen(value_name); str = new char[len + 256]; memset(str, 0, len + 256); sprintf(str,"%s=%s", key_name, value_name); len = strlen(str); pos = GotoNextLine(pos); //提行 m_str_data = (char *)realloc(m_str_data, m_data_length + len); //重新分配内存 char *temp = new char[m_data_length - pos]; memcpy(temp, &m_str_data[pos], m_data_length - pos); memcpy(&m_str_data[pos + len], temp, m_data_length - pos); //把后面的搬到末尾 memcpy(&m_str_data[pos], str, len); m_data_length += len; SAFE_DELETE(temp); SAFE_DELETE(str); return true; }
void InitMap(void) { int i = 0; int iLength = 0; ptagLevelCollection pCollection; iLength = sizeof(level_data_level); theMap = (ptagMap)calloc(1, sizeof(Map)); theMap->iNoOfCollection = 0; theMap->head = NULL; theMap->tail = NULL; theMap->currentLevel = NULL; while( i < iLength ) { if (LineType(i) == LINE_TYPE_COLLECTION_BEGIN) { pCollection = InitACollection(&i); //Insert the struct in the doube list. if (theMap->head == NULL) { theMap->head = pCollection; theMap->tail = theMap->head; pCollection->next = pCollection; pCollection->prev = pCollection; } else { pCollection->next = theMap->tail->next; pCollection->next->prev = pCollection; pCollection->prev = theMap->tail; theMap->tail->next = pCollection; theMap->tail = pCollection; } theMap->iNoOfCollection++; } else GotoNextLine(&i); } theMap->current = theMap->head; for (i = 0; i < BACK_STEP_SIZE; i++) theMap->pSteps[i] = NULL; PlayRestart(); }
/*================================================================ * 函数名: ReadText * 参数: [in] (int file_pos)文件的当前位置 * 功能描述: 在指定位置读一NAME字符串 * 返回值: 成功则返回NAME字符串, 否则返回空 ================================================================*/ char *CIni::ReadText(int file_pos) { char chr = NULL; char *value_name = NULL; int index_start = file_pos; int line_num = GotoNextLine(file_pos) - file_pos; value_name = new char[line_num]; memset(value_name, 0, line_num); for (int i = 0; i < m_data_length - file_pos; i++) { chr = m_str_data[index_start]; //结束 if (chr == ';' || chr == ' ' || chr == ']' || chr == '\n' || chr == '\r' || chr == '#') { return value_name; } value_name[i] = chr; index_start++; } return value_name; }
/***************************************************************************** * ParseSSAHeader: Retrieve global formatting information etc *****************************************************************************/ static void ParseSSAHeader( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; char *psz_parser = NULL; char *psz_header = malloc( p_dec->fmt_in.i_extra+1 ); int i_section_type = 1; memcpy( psz_header, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra ); psz_header[ p_dec->fmt_in.i_extra] = '\0'; /* Handle [Script Info] section */ psz_parser = strcasestr( psz_header, "[Script Info]" ); if( psz_parser == NULL ) goto eof; psz_parser = GotoNextLine( psz_parser ); while( psz_parser[0] != '\0' ) { int temp; char buffer_text[MAX_LINE + 1]; if( psz_parser[0] == '!' || psz_parser[0] == ';' ) /* comment */; else if( sscanf( psz_parser, "PlayResX: %d", &temp ) == 1 ) p_sys->i_original_width = ( temp > 0 ) ? temp : -1; else if( sscanf( psz_parser, "PlayResY: %d", &temp ) == 1 ) p_sys->i_original_height = ( temp > 0 ) ? temp : -1; else if( sscanf( psz_parser, "Script Type: %8192s", buffer_text ) == 1 ) { if( !strcasecmp( buffer_text, "V4.00+" ) ) p_sys->b_ass = VLC_TRUE; } else if( !strncasecmp( psz_parser, "[V4 Styles]", 11 ) ) i_section_type = 1; else if( !strncasecmp( psz_parser, "[V4+ Styles]", 12) ) { i_section_type = 2; p_sys->b_ass = VLC_TRUE; } else if( !strncasecmp( psz_parser, "[Events]", 8 ) ) i_section_type = 4; else if( !strncasecmp( psz_parser, "Style:", 6 ) ) { int i_font_size, i_bold, i_italic, i_border, i_outline, i_shadow, i_underline, i_strikeout, i_scale_x, i_scale_y, i_spacing, i_align, i_margin_l, i_margin_r, i_margin_v; char psz_temp_stylename[MAX_LINE+1]; char psz_temp_fontname[MAX_LINE+1]; char psz_temp_color1[MAX_LINE+1]; char psz_temp_color2[MAX_LINE+1]; char psz_temp_color3[MAX_LINE+1]; char psz_temp_color4[MAX_LINE+1]; if( i_section_type == 1 ) /* V4 */ { if( sscanf( psz_parser, "Style: %8192[^,],%8192[^,],%d,%8192[^,],%8192[^,],%8192[^,],%8192[^,],%d,%d,%d,%d,%d,%d,%d,%d,%d%*[^\r\n]", psz_temp_stylename, psz_temp_fontname, &i_font_size, psz_temp_color1, psz_temp_color2, psz_temp_color3, psz_temp_color4, &i_bold, &i_italic, &i_border, &i_outline, &i_shadow, &i_align, &i_margin_l, &i_margin_r, &i_margin_v ) == 16 ) { ssa_style_t *p_style = malloc( sizeof(ssa_style_t) ); p_style->psz_stylename = strdup( psz_temp_stylename ); p_style->font_style.psz_fontname = strdup( psz_temp_fontname ); p_style->font_style.i_font_size = i_font_size; ParseColor( p_dec, psz_temp_color1, &p_style->font_style.i_font_color, NULL ); ParseColor( p_dec, psz_temp_color4, &p_style->font_style.i_shadow_color, NULL ); p_style->font_style.i_outline_color = p_style->font_style.i_shadow_color; p_style->font_style.i_font_alpha = p_style->font_style.i_outline_alpha = p_style->font_style.i_shadow_alpha = 0x00; p_style->font_style.i_style_flags = 0; if( i_bold ) p_style->font_style.i_style_flags |= STYLE_BOLD; if( i_italic ) p_style->font_style.i_style_flags |= STYLE_ITALIC; if( i_border == 1 ) p_style->font_style.i_style_flags |= (STYLE_ITALIC | STYLE_OUTLINE); else if( i_border == 3 ) { p_style->font_style.i_style_flags |= STYLE_BACKGROUND; p_style->font_style.i_background_color = p_style->font_style.i_shadow_color; p_style->font_style.i_background_alpha = p_style->font_style.i_shadow_alpha; } p_style->font_style.i_shadow_width = i_shadow; p_style->font_style.i_outline_width = i_outline; p_style->i_align = 0; if( i_align == 1 || i_align == 5 || i_align == 9 ) p_style->i_align |= SUBPICTURE_ALIGN_LEFT; if( i_align == 3 || i_align == 7 || i_align == 11 ) p_style->i_align |= SUBPICTURE_ALIGN_RIGHT; if( i_align < 4 ) p_style->i_align |= SUBPICTURE_ALIGN_BOTTOM; else if( i_align < 8 ) p_style->i_align |= SUBPICTURE_ALIGN_TOP; p_style->i_margin_h = ( p_style->i_align & SUBPICTURE_ALIGN_RIGHT ) ? i_margin_r : i_margin_l; p_style->i_margin_v = i_margin_v; TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_style ); } else msg_Warn( p_dec, "SSA v4 styleline parsing failed" ); } else if( i_section_type == 2 ) /* V4+ */ { /* Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding */ if( sscanf( psz_parser, "Style: %8192[^,],%8192[^,],%d,%8192[^,],%8192[^,],%8192[^,],%8192[^,],%d,%d,%d,%d,%d,%d,%d,%*f,%d,%d,%d,%d,%d,%d,%d%*[^\r\n]", psz_temp_stylename, psz_temp_fontname, &i_font_size, psz_temp_color1, psz_temp_color2, psz_temp_color3, psz_temp_color4, &i_bold, &i_italic, &i_underline, &i_strikeout, &i_scale_x, &i_scale_y, &i_spacing, &i_border, &i_outline, &i_shadow, &i_align, &i_margin_l, &i_margin_r, &i_margin_v ) == 21 ) { ssa_style_t *p_style = malloc( sizeof(ssa_style_t) ); p_style->psz_stylename = strdup( psz_temp_stylename ); p_style->font_style.psz_fontname = strdup( psz_temp_fontname ); p_style->font_style.i_font_size = i_font_size; msg_Dbg( p_dec, psz_temp_color1 ); ParseColor( p_dec, psz_temp_color1, &p_style->font_style.i_font_color, &p_style->font_style.i_font_alpha ); ParseColor( p_dec, psz_temp_color3, &p_style->font_style.i_outline_color, &p_style->font_style.i_outline_alpha ); ParseColor( p_dec, psz_temp_color4, &p_style->font_style.i_shadow_color, &p_style->font_style.i_shadow_alpha ); p_style->font_style.i_style_flags = 0; if( i_bold ) p_style->font_style.i_style_flags |= STYLE_BOLD; if( i_italic ) p_style->font_style.i_style_flags |= STYLE_ITALIC; if( i_underline ) p_style->font_style.i_style_flags |= STYLE_UNDERLINE; if( i_strikeout ) p_style->font_style.i_style_flags |= STYLE_STRIKEOUT; if( i_border == 1 ) p_style->font_style.i_style_flags |= (STYLE_ITALIC | STYLE_OUTLINE); else if( i_border == 3 ) { p_style->font_style.i_style_flags |= STYLE_BACKGROUND; p_style->font_style.i_background_color = p_style->font_style.i_shadow_color; p_style->font_style.i_background_alpha = p_style->font_style.i_shadow_alpha; } p_style->font_style.i_shadow_width = ( i_border == 1 ) ? i_shadow : 0; p_style->font_style.i_outline_width = ( i_border == 1 ) ? i_outline : 0; p_style->font_style.i_spacing = i_spacing; //p_style->font_style.f_angle = f_angle; p_style->i_align = 0; if( i_align == 0x1 || i_align == 0x4 || i_align == 0x1 ) p_style->i_align |= SUBPICTURE_ALIGN_LEFT; if( i_align == 0x3 || i_align == 0x6 || i_align == 0x9 ) p_style->i_align |= SUBPICTURE_ALIGN_RIGHT; if( i_align == 0x7 || i_align == 0x8 || i_align == 0x9 ) p_style->i_align |= SUBPICTURE_ALIGN_TOP; if( i_align == 0x1 || i_align == 0x2 || i_align == 0x3 ) p_style->i_align |= SUBPICTURE_ALIGN_BOTTOM; p_style->i_margin_h = ( p_style->i_align & SUBPICTURE_ALIGN_RIGHT ) ? i_margin_r : i_margin_l; p_style->i_margin_v = i_margin_v; /*TODO: Ignored: angle i_scale_x|y (fontscaling), i_encoding */ TAB_APPEND( p_sys->i_ssa_styles, p_sys->pp_ssa_styles, p_style ); } else msg_Dbg( p_dec, "SSA V4+ styleline parsing failed" ); } } psz_parser = GotoNextLine( psz_parser ); } eof: if( psz_header ) free( psz_header ); return; }
//align at alphabit static ptagLevelCollection InitACollection(int * i) { ptagLevelCollection pCollection; char * name; int iNameLength = 0; int j = *i; char a; ptagLevel pLevel; int iLevel = 1; int iType; pCollection = (ptagLevelCollection)calloc(1, sizeof(LevelCollection)); pCollection->iNoOfLevels = 0; pCollection->strName = (char *)calloc(MAX_COLLECTION_NAME, sizeof(char)); name = pCollection->strName; pCollection->head = NULL; pCollection->tail = NULL; assert (LineType(j) == LINE_TYPE_COLLECTION_BEGIN); //first get the name do { a = (char)level_data_level[j]; if((isalpha(a)) || (a == '_')){ name[iNameLength++] = a; j++; } else break; } while(1); GotoNextLine(&j); name[iNameLength] = '\0'; while(1) { iType = LineType(j); if (iType == LINE_TYPE_COLLECTION_BEGIN) break; //finished this collection if (iType == LINE_TYPE_LEVEL_BEGIN){ pLevel = InitALevel(&j); pLevel->iNo = iLevel++; if (pCollection->head == NULL) { pCollection->head = pLevel; pCollection->tail = pCollection->head; pLevel->next = pLevel; pLevel->prev = pLevel; } else { pLevel->next = pCollection->tail->next; pLevel->next->prev = pLevel; pLevel->prev = pCollection->tail; pCollection->tail->next = pLevel; pCollection->tail = pLevel; } pCollection->iNoOfLevels++; } else GotoNextLine(&j); } *i = j; pCollection->current = pCollection->head; return pCollection; }
//we begin at the begin of a line static ptagLevel InitALevel(int *i) { ptagLevel pLevel; int j = *i; int iLineBegin = 0; int iLineEnd = 0; int iRow = 0; int iCol = 0; char a; int *pInt; int k; int b; assert (LineType(j) == LINE_TYPE_LEVEL_BEGIN); //first decide how many line rows iLineBegin = j; while(1) { //we are now at the begin of the line a = (char)level_data_level[j]; while (a != 0x0a) { if (a == '#') iLineEnd = j; a = (char)level_data_level[++j]; } if (iLineEnd == 0) //There are no '#'s in this line. break; if (iLineEnd -iLineBegin + 1 > iCol) iCol = iLineEnd - iLineBegin + 1; iRow ++; j++; iLineEnd = 0; iLineBegin = j; } //Init a structure pLevel = (ptagLevel)calloc(1, sizeof(Level)); pLevel->row = iRow; pLevel->col = iCol; pLevel->data = (int *)calloc(iRow*iCol, sizeof(int)); pInt = pLevel->data; //set value to pLevel->data j = *i; for(iRow = 0; iRow < pLevel->row; iRow++) { iLineEnd = FindLineEnd(j); for(k = 0; k <= iLineEnd; k++) { b = level_data_level[j++]; switch (b) { case '@': pLevel->manx = k; pLevel->many = iRow; pInt[iRow*iCol+k] = B_MAN; break; case '$': pInt[iRow*iCol+k] = B_OBJECT; break; case '.': pInt[iRow*iCol+k] = B_GOAL; break; case '*': pInt[iRow*iCol+k] = B_TREASURE; break; case '+': pLevel->manx = k; pLevel->many = iRow; pInt[iRow*iCol+k] = B_SAVEMAN; break; case '#': pInt[iRow*iCol+k] = B_STONE; break; default: pInt[iRow*iCol+k] = B_NOTHING; } } for ( ; k < iCol; k++) pInt[iRow*iCol+k] = B_NOTHING; GotoNextLine(&j); } *i = j; return pLevel; }
/* ***************************************************************************** ** FUNCTION NAME: ReadHttpContent ** ** FUNCTION INPUTS: ** @int fd: fd ** @fd_set *prdfds: fd_set ** @int timeout: timeout ** @PHTTP_RESPONSE pHttp: ** @int chunked: 0=> not chunkd encoding, 1=> chunked encoding ** ** FUNCTION DESCRIPTION ** This function will read http content from fd and package HTTP_RESPONSE. ** ** FUNCTION OUTPUTS: ** ZAPP_SUCCESS -> success ** ZAPP_TIMEOUT -> timeout ** ZAPP_FAILED -> other reason ** ** HISTORY: ** 2008-7-11 Steven Leong Created ***************************************************************************** */ int ReadHttpContent(int fd, fd_set *prdfds, int timeout, PHTTP_RESPONSE pHttp, int chunked) { Z_BUF zBuf; struct timeval tv; char bufArray[BUF_1024_BITS]; U32 lefttime, starttime, curtime; int n, nRet = ZAPP_SUCCESS; //for chunked Z_BUF zBufChunk; char *ptr = NULL; int size; tv.tv_usec = 0; ZUtilBufInit(&zBuf, 0); ptr = &zBuf.buf[0]; lefttime = timeout; starttime = GetUptime(); while(1) { tv.tv_sec = lefttime; select (fd+1, prdfds, NULL, NULL, &tv); if(FD_ISSET (fd, prdfds)){ memset(bufArray, 0, BUF_1024_BITS); n = read(fd, bufArray, BUF_1024_BITS-1); /* Calculate lefttime */ if((curtime = GetUptime()) > 0){ lefttime -= curtime - starttime; starttime = curtime; } if(lefttime <= 0){ /* timeout */ nRet = ZAPP_TIMEOUT; goto appOut; } if(n < 0){ if( errno == EAGAIN) continue; else { /* pipe error */ dprintf("pipe error.\n"); nRet = ZAPP_FAILED; goto appOut; } } else if(n == 0){ /* The server close the socket */ //NOTE: we are reading the header. don't allow to close. */ dprintf("The server close the socket.\n"); if(chunked == 1) goto parseChunked; else goto readDone; } //dprintf("Read Buf(%d)-> %s\n", n, bufArray); ZBufAttach(&zBuf, bufArray, n); if(chunked == 1){ /* Chunked encoding */ //NOTE: "\r\n0\r\n" for end flag if(strstr(ptr, CRLF"0"CRLF) == NULL){ /* NOTE:zBuf.length-10 is very import. e.g. If former read is "xxxx\r", and this time is "\n0\r\n\r\n", it will make right.*/ if(zBuf.length > 10) ptr = &zBuf.buf[zBuf.length-10]; else ptr = &zBuf.buf[0]; } else goto parseChunked; } else{ /* Normal */ if(zBuf.length >= pHttp->header.contentLength) goto readDone; } } else{ /* timeout */ nRet = ZAPP_TIMEOUT; goto appOut; } } appOut: ZUtilBufDestroy(&zBuf); return nRet; readDone: //Done. Copy the content dprintf("Normal content Done.\n"); pHttp->contentSize = pHttp->header.contentLength; pHttp->content = zBuf.buf; zBuf.buf = NULL; ZUtilBufDestroy(&zBuf); return ZAPP_SUCCESS; parseChunked: dprintf("Chunk content done.\n"); ZUtilBufInit(&zBufChunk, 0); ptr = &zBuf.buf[0]; while(1){ //Try to find out the chunked length //NOTE: chunked is the Hex format n = sscanf(ptr, "%x"CRLF, &size); if(n <= 0 || size == 0) break; dprintf(">>>>>> ChunkSize:%d(%x)\n", size, size); pHttp->header.contentLength += size; ptr += GotoNextLine(ptr)+strlen(CRLF); ZBufAttach(&zBufChunk, ptr, size); ptr += (size+1); }; pHttp->header.contentLength = zBufChunk.length; pHttp->contentSize = pHttp->header.contentLength; pHttp->content = zBufChunk.buf; zBufChunk.buf = NULL; ZUtilBufDestroy(&zBufChunk); ZUtilBufDestroy(&zBuf); return ZAPP_SUCCESS; }