@@ -10,13 +10,24 @@ type Reader interface {
10
10
Read () (* Object , error )
11
11
}
12
12
13
- // NewReader creates a new reader from the given io reader
13
+ // NewReader creates a new reader frrouter the given io reader
14
14
func NewReader (r io.Reader ) Reader {
15
- return & stdReader {r }
15
+ sr := & stdReader {
16
+ r : r ,
17
+ router : make (objectRouter ),
18
+ }
19
+ sr .router ["#" ] = commentHandler
20
+ sr .router ["o" ] = objectHandler
21
+ sr .router ["v" ] = vertexHandler
22
+ sr .router ["vn" ] = normalHandler
23
+ sr .router ["vt" ] = textureHandler
24
+ sr .router ["f" ] = faceHandler
25
+ return sr
16
26
}
17
27
18
28
type stdReader struct {
19
- r io.Reader
29
+ r io.Reader
30
+ router objectRouter
20
31
}
21
32
22
33
func (r * stdReader ) Read () (* Object , error ) {
@@ -43,54 +54,79 @@ func (r *stdReader) Read() (*Object, error) {
43
54
}
44
55
45
56
func (r * stdReader ) readLine (line []byte , lineNumber int64 , o * Object ) error {
46
-
47
- //TODO: cyclomic complexity is 11. Would a 'router' be better here?
48
-
49
57
if len (line ) == 0 {
50
58
return nil
51
59
}
52
60
53
61
tokens := splitByToken (line , ' ' )
54
- rest := tokens [1 :]
55
62
56
- switch string (tokens [0 ]) {
57
- case "#" :
58
- // skip comments
59
- return nil
60
- case "o" :
61
- o .Name = string (tokens [1 ])
62
- case "v" :
63
- v , err := parseVertex (rest )
64
- if err != nil {
65
- return wrapParseErrors (lineNumber , "vertex (v)" , err )
66
- }
67
- o .Vertices = append (o .Vertices , v )
68
- return nil
69
- case "vn" :
70
- vn , err := parseNormal (rest )
71
- if err != nil {
72
- return wrapParseErrors (lineNumber , "vertexNormal (vn)" , err )
73
- }
74
- o .Normals = append (o .Normals , vn )
75
- return nil
76
- case "vt" :
77
- vt , err := parseTextCoord (rest )
78
- if err != nil {
79
- return wrapParseErrors (lineNumber , "textureCoordinate (vt)" , err )
80
- }
63
+ if _ , err := r .router .Route (o , tokens ... ); err != nil {
64
+ return wrapLineNumber (lineNumber , err )
65
+ }
81
66
82
- o .Textures = append (o .Textures , vt )
83
- case "f" :
84
- f , err := parseFace (rest , o )
85
- if err != nil {
86
- return wrapParseErrors (lineNumber , "face (f)" , err )
87
- }
88
- o .Faces = append (o .Faces , f )
89
- return nil
90
- default :
91
- // fmt.Printf("ignoring token: %s\n", tokens[0])
92
- return nil
67
+ return nil
68
+ }
69
+
70
+ func commentHandler (o * Object , rest ... []byte ) error {
71
+ return nil
72
+ }
73
+
74
+ func objectHandler (o * Object , rest ... []byte ) error {
75
+ o .Name = string (rest [0 ])
76
+ return nil
77
+ }
78
+
79
+ func vertexHandler (o * Object , rest ... []byte ) error {
80
+ v , err := parseVertex (rest )
81
+ if err != nil {
82
+ return wrapParseErrors ("vertex (v)" , err )
93
83
}
84
+ o .Vertices = append (o .Vertices , v )
85
+ return nil
86
+ }
94
87
88
+ func normalHandler (o * Object , rest ... []byte ) error {
89
+ vn , err := parseNormal (rest )
90
+ if err != nil {
91
+ return wrapParseErrors ("vertexNormal (vn)" , err )
92
+ }
93
+ o .Normals = append (o .Normals , vn )
95
94
return nil
96
95
}
96
+
97
+ func textureHandler (o * Object , rest ... []byte ) error {
98
+ vt , err := parseTextCoord (rest )
99
+ if err != nil {
100
+ return wrapParseErrors ("textureCoordinate (vt)" , err )
101
+ }
102
+
103
+ o .Textures = append (o .Textures , vt )
104
+ return nil
105
+ }
106
+
107
+ func faceHandler (o * Object , rest ... []byte ) error {
108
+ f , err := parseFace (rest , o )
109
+ if err != nil {
110
+ return wrapParseErrors ("face (f)" , err )
111
+ }
112
+ o .Faces = append (o .Faces , f )
113
+ return nil
114
+ }
115
+
116
+ type objectRouter map [string ]func (* Object , ... []byte ) error
117
+
118
+ // Route returns true if the list of tokens has been routed, false if it has been skipped
119
+ func (router objectRouter ) Route (o * Object , tokens ... []byte ) (bool , error ) {
120
+ r , ok := router [string (tokens [0 ])]
121
+ if ! ok {
122
+ return false , nil
123
+ }
124
+ rest := tokens [1 :]
125
+
126
+ err := r (o , rest ... )
127
+ if err != nil {
128
+ return false , err
129
+ }
130
+
131
+ return true , nil
132
+ }
0 commit comments