@@ -173,36 +173,53 @@ static bool Consume(char expected, string json, ref int index, bool required = t
173
173
index ++ ;
174
174
return true ;
175
175
} else if ( required ) {
176
- throw new System . Exception ( "expected " + expected + " at index " + index ) ;
176
+ throw new FbxPrefabException ( string . Format (
177
+ "expected {0} at index {1} in [{2}]" ,
178
+ expected , index , json ) ) ;
177
179
} else {
178
180
return false ;
179
181
}
180
182
}
181
183
}
182
184
183
- // %-escape a string to make sure that " and \ are set up to be easy to parse
184
- static string EscapeString ( string str ) {
185
+ static string ReadString ( string json , ref int index ) {
186
+ int startIndex = index ;
187
+ Consume ( '"' , json , ref index ) ;
185
188
var builder = new System . Text . StringBuilder ( ) ;
186
- foreach ( var c in str ) {
187
- switch ( c ) {
188
- case '%' : builder . Append ( "%25" ) ; break ;
189
- case ' \\ ' : builder . Append ( "%5c" ) ; break ;
190
- case '"' : builder . Append ( "%22" ) ; break ;
191
- default : builder . Append ( c ) ; break ;
189
+ while ( json [ index ] != '"' ) {
190
+ if ( index == json . Length ) {
191
+ throw new FbxPrefabException (
192
+ string . Format ( "Unterminated quote in string starting at index {0}: [{1}]" ,
193
+ startIndex , json ) ) ;
194
+
192
195
}
196
+ if ( json [ index ] == '\\ ' ) {
197
+ // A backslash followed by a backslash or a quote outputs the
198
+ // next character. Otherwise it outputs itself.
199
+ if ( index + 1 < json . Length ) {
200
+ switch ( json [ index + 1 ] ) {
201
+ case '\\ ' :
202
+ case '"' :
203
+ index ++ ;
204
+ break ;
205
+ }
206
+ }
207
+ }
208
+ builder . Append ( json [ index ] ) ;
209
+ index ++ ;
193
210
}
211
+ Consume ( '"' , json , ref index ) ;
194
212
return builder . ToString ( ) ;
195
213
}
196
214
197
- static string UnEscapeString ( string str , int index , int len ) {
215
+ // Escape a string so that ReadString can read it.
216
+ static string EscapeString ( string str ) {
198
217
var builder = new System . Text . StringBuilder ( ) ;
199
- for ( int i = index ; i < index + len ; ++ i ) {
200
- if ( str [ i ] != '%' ) {
201
- builder . Append ( str [ i ] ) ;
202
- } else {
203
- string number = str . Substring ( i + 1 , 2 ) ;
204
- int ord = System . Convert . ToInt32 ( number , 16 ) ;
205
- builder . Append ( ( char ) ord ) ;
218
+ foreach ( var c in str ) {
219
+ switch ( c ) {
220
+ case '\\ ' : builder . Append ( "\\ \\ " ) ; break ;
221
+ case '"' : builder . Append ( "\\ \" " ) ; break ;
222
+ default : builder . Append ( c ) ; break ;
206
223
}
207
224
}
208
225
return builder . ToString ( ) ;
@@ -216,32 +233,18 @@ void InitFromJson(string json, ref int index)
216
233
return ;
217
234
} else {
218
235
do {
219
- Consume ( '"' , json , ref index ) ;
220
- int nameStart = index ;
221
- while ( json [ index ] != '"' ) { index ++ ; }
222
- string name = json . Substring ( nameStart , index - nameStart ) ;
223
- index ++ ;
236
+ string name = ReadString ( json , ref index ) ;
224
237
Consume ( ':' , json , ref index ) ;
225
- // if name starts with - it's a child; otherwise it's a
226
- // component (which can't start with a - because it's
227
- // the name of a C# type)
228
- if ( name [ 0 ] == '-' ) {
238
+
239
+ // hack: If the name starts with a '-' it's the name
240
+ // of a gameobject, and we parse it recursively. Otherwise
241
+ // it's the name of a component, and we store its value as a string.
242
+ bool isChild = ( name . Length > 0 ) && ( name [ 0 ] == '-' ) ;
243
+ if ( isChild ) {
229
244
var subrep = new FbxRepresentation ( json , ref index ) ;
230
245
Add ( ref m_children , name . Substring ( 1 ) , subrep ) ;
231
246
} else {
232
- // Read the string. It won't have any quote marks
233
- // in it, because we escape them using %-encoding
234
- // like in a URL.
235
- Consume ( '"' , json , ref index ) ;
236
- int componentStart = index ;
237
- while ( json [ index ] != '"' ) { index ++ ; }
238
- index ++ ;
239
-
240
- // We %-escaped the string so there would be no
241
- // quotes (nor backslashes that might confuse other
242
- // json parsers), now undo that.
243
- var jsonComponent =
244
- UnEscapeString ( json , componentStart , index - componentStart ) ;
247
+ string jsonComponent = ReadString ( json , ref index ) ;
245
248
Append ( ref m_components , name , jsonComponent ) ;
246
249
}
247
250
} while ( Consume ( ',' , json , ref index , required : false ) ) ;
@@ -625,20 +628,17 @@ void ClassifyComponents(Transform newFbx)
625
628
626
629
// TODO: handle multiplicity! The algorithm is eluding me right now...
627
630
// We'll need to do some kind of 3-way matching.
631
+ if ( oldValues . Count > 1 ) { Debug . LogError ( "TODO: handle multiplicity " + oldValues . Count ) ; }
632
+ if ( newValues . Count > 1 ) { Debug . LogError ( "TODO: handle multiplicity " + newValues . Count ) ; }
633
+ if ( prefabValues . Count > 1 ) { Debug . LogError ( "TODO: handle multiplicity " + prefabValues . Count ) ; }
634
+
628
635
if ( oldValues . Count == 0 && newValues . Count != 0 && prefabValues . Count == 0 ) {
629
- if ( newValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + newValues . Count ) ; }
630
636
Append ( ref typesToUpdate , typename ) ;
631
637
}
632
638
else if ( oldValues . Count != 0 && newValues . Count == 0 && prefabValues . Count != 0 ) {
633
- if ( oldValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + oldValues . Count ) ; }
634
- if ( prefabValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + prefabValues . Count ) ; }
635
639
Append ( ref typesToDestroy , typename ) ;
636
640
}
637
641
else if ( oldValues . Count != 0 && newValues . Count != 0 && prefabValues . Count != 0 ) {
638
- if ( oldValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + oldValues . Count ) ; }
639
- if ( newValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + newValues . Count ) ; }
640
- if ( prefabValues . Count != 1 ) { Debug . LogError ( "TODO: handle multiplicity " + prefabValues . Count ) ; }
641
-
642
642
// Check whether we need to update.
643
643
var oldValue = oldValues [ 0 ] ;
644
644
var newValue = newValues [ 0 ] ;
@@ -649,6 +649,7 @@ void ClassifyComponents(Transform newFbx)
649
649
// if oldValue != prefabValue, conflict =>
650
650
// resolve in favor of Chris, so update
651
651
// anyway.
652
+ Debug . Log ( string . Format ( "{0}\n {1}\n Differ" , oldValue , newValue ) ) ;
652
653
Append ( ref typesToUpdate , typename ) ;
653
654
}
654
655
}
0 commit comments