indexing description: "Direct X format parsing helpers" date: "$Date$" revision: "$Revision$" class EM3D_X_PARSING_SUPPORT feature -- Implementation skip_one( a_file: PLAIN_TEXT_FILE; a_character: CHARACTER ) is -- Skip excactly one a_character and any whitespace, comments local done: BOOLEAN do from until done or a_file.after loop from a_file.read_character until a_file.end_of_file or else not a_file.last_character.is_space loop a_file.read_character end if a_file.last_character='/' then a_file.read_character if a_file.last_character='/' then a_file.read_line else done := true end a_file.back elseif a_file.last_character.item='#' then a_file.read_line else done := true end end end skip( a_file: PLAIN_TEXT_FILE; a_character: CHARACTER ) is -- Skip a_character and any whitespace, comments local done: BOOLEAN do from until done or a_file.after loop from a_file.read_character until a_file.end_of_file or else not a_file.last_character.is_space loop a_file.read_character end done := a_file.last_character /= a_character if a_file.last_character='/' then a_file.read_character if a_file.last_character='/' then a_file.read_line done := false end a_file.back elseif a_file.last_character.item='#' then a_file.read_line done := false end end a_file.back end parse_string( a_file: PLAIN_TEXT_FILE ): STRING is do create result.make_empty from skip( a_file, '"' ) until a_file.item='"' loop result.append_character( a_file.item ) a_file.forth end end parse_double( a_file: PLAIN_TEXT_FILE ): DOUBLE is do a_file.read_double result := a_file.last_double skip ( a_file, ',' ) skip ( a_file, ';' ) end parse_integer( a_file: PLAIN_TEXT_FILE ): INTEGER is do a_file.read_integer result := a_file.last_integer skip ( a_file, ',' ) skip ( a_file, ';' ) end parse_matrix44( a_file: PLAIN_TEXT_FILE ):EM_MATRIX44 is local i,j : INTEGER do -- DirectX uses row major!! -- This look awful in the file :) from i:=1 until i>4 loop from j:=1 until j>4 loop result[j,i] := parse_double( a_file ) j:=j+1 end i:=i+1 end end parse_vector4d( a_file: PLAIN_TEXT_FILE ):EM_VECTOR4D is do result.x := parse_double( a_file ) result.y := parse_double( a_file ) result.z := parse_double( a_file ) result.w := parse_double( a_file ) end parse_vector3d( a_file: PLAIN_TEXT_FILE ):EM_VECTOR3D is do result.x := parse_double( a_file ) result.y := parse_double( a_file ) result.z := parse_double( a_file ) end parse_vector2d( a_file: PLAIN_TEXT_FILE ):EM_VECTOR2D is do result.x := parse_double( a_file ) result.y := parse_double( a_file ) end parse_face( a_file: PLAIN_TEXT_FILE ): ARRAY[ INTEGER ] is local count, i: INTEGER do count := parse_integer( a_file ) create result.make( 1, count ) result[1] := parse_integer( a_file ) from i:=2 until i>count loop skip ( a_file, ',' ) result[i] := parse_integer( a_file ) i := i + 1 end skip ( a_file, ';' ) end skip_block( a_file: PLAIN_TEXT_FILE ) is local count: INTEGER found: BOOLEAN do if not a_file.end_of_file then -- a_file.search is crap, it produces an enless loop, bravo ISE -- a_file.search ( '{' ) a_file.forth count := 0 found := false from a_file.read_character until (found and count=0) or a_file.end_of_file loop if a_file.last_character='{' then count := count + 1 found := true elseif a_file.last_character='}' then count := count - 1 end a_file.read_character end if found and count=0 then a_file.back end end end parse_integer_array( a_file: PLAIN_TEXT_FILE ): ARRAY[ INTEGER ] is local i: INTEGER do create result.make(0, parse_integer( a_file )-1 ) from i:=result.lower until i>result.upper loop -- Read a integer result.put ( parse_integer( a_file ) , i) i:=i+1 if i>result.upper then skip ( a_file, ';' ) else skip ( a_file, ',' ) end end end parse_vector3d_array( a_file: PLAIN_TEXT_FILE ): ARRAY[ EM_VECTOR3D ] is local i: INTEGER do create result.make(0, parse_integer( a_file )-1 ) from i:=result.lower until i>result.upper loop -- Read a vertex result.put ( parse_vector3d( a_file ) , i) i:=i+1 if i>result.upper then skip ( a_file, ';' ) else skip ( a_file, ',' ) end end end parse_vector2d_array( a_file: PLAIN_TEXT_FILE ): ARRAY[ EM_VECTOR2D ] is local i: INTEGER do create result.make(0, parse_integer( a_file )-1 ) from i:=result.lower until i>result.upper loop -- Read a vertex result.put ( parse_vector2d( a_file ) , i) i:=i+1 if i>result.upper then skip ( a_file, ';' ) else skip ( a_file, ',' ) end end end parse_face_array( a_file: PLAIN_TEXT_FILE ): ARRAY[ ARRAY[INTEGER] ] is local i: INTEGER face: ARRAY[ INTEGER ] do create result.make (0, parse_integer( a_file )-1) from i:=result.lower until i>result.upper loop result[i] := parse_face( a_file ) i := i + 1 if i>result.upper then skip ( a_file, ';' ) else skip ( a_file, ',' ) end end end skip_to( a_file: PLAIN_TEXT_FILE; a_character: CHARACTER ) is -- Since a_file.search gives a nice endless loop, I had rewrite it :( do if a_file.item /= a_character then from a_file.read_character until a_file.last_character = a_character or a_file.end_of_file loop a_file.read_character end end end end