@@ -78,60 +78,60 @@ private string SerializeComplex(object input) {
7878
7979 switch ( input ) {
8080 case PhpDynamicObject dynamicObject : {
81- var className = dynamicObject . GetClassName ( ) ?? "stdClass" ;
82- ICollection < string > memberNames = dynamicObject . GetDynamicMemberNames ( ) ;
83- string preamble = $ "O:{ className . Length } :\" { className } \" :{ memberNames . Count } :{{";
84- string [ ] entryStrings = new string [ memberNames . Count * 2 ] ;
85- int entryIndex = 0 ;
86- foreach ( var memberName in memberNames ) {
87- entryStrings [ entryIndex ] = this . Serialize ( memberName ) ;
88- entryStrings [ entryIndex + 1 ] = this . Serialize ( dynamicObject . GetMember ( memberName ) ) ;
89- entryIndex += 2 ;
90- }
91- return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
81+ var className = dynamicObject . GetClassName ( ) ?? "stdClass" ;
82+ ICollection < string > memberNames = dynamicObject . GetDynamicMemberNames ( ) ;
83+ string preamble = $ "O:{ className . Length } :\" { className } \" :{ memberNames . Count } :{{";
84+ string [ ] entryStrings = new string [ memberNames . Count * 2 ] ;
85+ int entryIndex = 0 ;
86+ foreach ( var memberName in memberNames ) {
87+ entryStrings [ entryIndex ] = this . Serialize ( memberName ) ;
88+ entryStrings [ entryIndex + 1 ] = this . Serialize ( dynamicObject . GetMember ( memberName ) ) ;
89+ entryIndex += 2 ;
9290 }
91+ return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
92+ }
9393 case ExpandoObject expando : {
94- var dictionary = ( IDictionary < string , object > ) expando ;
95- string preamble = $ "O:8:\" stdClass\" :{ dictionary . Keys . Count } :{{";
96-
97- string [ ] entryStrings = new string [ dictionary . Count * 2 ] ;
98- int entryIndex = 0 ;
99- foreach ( var entry in dictionary ) {
100- entryStrings [ entryIndex ] = this . Serialize ( entry . Key ) ;
101- entryStrings [ entryIndex + 1 ] = this . Serialize ( entry . Value ) ;
102- entryIndex += 2 ;
103- }
104- return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
94+ var dictionary = ( IDictionary < string , object > ) expando ;
95+ string preamble = $ "O:8:\" stdClass\" :{ dictionary . Keys . Count } :{{";
96+
97+ string [ ] entryStrings = new string [ dictionary . Count * 2 ] ;
98+ int entryIndex = 0 ;
99+ foreach ( var entry in dictionary ) {
100+ entryStrings [ entryIndex ] = this . Serialize ( entry . Key ) ;
101+ entryStrings [ entryIndex + 1 ] = this . Serialize ( entry . Value ) ;
102+ entryIndex += 2 ;
105103 }
104+ return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
105+ }
106106 case IDynamicMetaObjectProvider :
107107 throw new NotSupportedException (
108108 "Serialization support for dynamic objects is limited to PhpSerializerNET.PhpDynamicObject and System.Dynamic.ExpandoObject in this version."
109109 ) ;
110110 case IDictionary dictionary : {
111- string preamble ;
112- if ( input is IPhpObject phpObject ) {
113- string className = phpObject . GetClassName ( ) ;
114- preamble = $ "O:{ className . Length } :\" { className } \" :{ dictionary . Count } :{{";
115- } else {
116- var dictionaryType = dictionary . GetType ( ) ;
117- if ( dictionaryType . GenericTypeArguments . Length > 0 ) {
118- var keyType = dictionaryType . GenericTypeArguments [ 0 ] ;
119- if ( ! keyType . IsIConvertible ( ) && keyType != typeof ( object ) ) {
120- throw new Exception ( $ "Can not serialize into associative array with key type { keyType . FullName } ") ;
121- }
111+ string preamble ;
112+ if ( input is IPhpObject phpObject ) {
113+ string className = phpObject . GetClassName ( ) ;
114+ preamble = $ "O:{ className . Length } :\" { className } \" :{ dictionary . Count } :{{";
115+ } else {
116+ var dictionaryType = dictionary . GetType ( ) ;
117+ if ( dictionaryType . GenericTypeArguments . Length > 0 ) {
118+ var keyType = dictionaryType . GenericTypeArguments [ 0 ] ;
119+ if ( ! keyType . IsIConvertible ( ) && keyType != typeof ( object ) ) {
120+ throw new Exception ( $ "Can not serialize into associative array with key type { keyType . FullName } ") ;
122121 }
123- preamble = $ "a:{ dictionary . Count } :{{";
124122 }
123+ preamble = $ "a:{ dictionary . Count } :{{";
124+ }
125125
126- string [ ] entryStrings = new string [ dictionary . Count * 2 ] ;
127- int entryIndex = 0 ;
128- foreach ( DictionaryEntry entry in dictionary ) {
129- entryStrings [ entryIndex ] = this . Serialize ( entry . Key ) ;
130- entryStrings [ entryIndex + 1 ] = this . Serialize ( entry . Value ) ;
131- entryIndex += 2 ;
132- }
133- return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
126+ string [ ] entryStrings = new string [ dictionary . Count * 2 ] ;
127+ int entryIndex = 0 ;
128+ foreach ( DictionaryEntry entry in dictionary ) {
129+ entryStrings [ entryIndex ] = this . Serialize ( entry . Key ) ;
130+ entryStrings [ entryIndex + 1 ] = this . Serialize ( entry . Value ) ;
131+ entryIndex += 2 ;
134132 }
133+ return string . Concat ( preamble , string . Concat ( entryStrings ) , "}" ) ;
134+ }
135135 case IList collection :
136136 string [ ] itemStrings = new string [ collection . Count * 2 ] ;
137137 for ( int i = 0 ; i < itemStrings . Length ; i += 2 ) {
@@ -144,45 +144,52 @@ private string SerializeComplex(object input) {
144144 "}"
145145 ) ;
146146 default : {
147- StringBuilder output = new StringBuilder ( ) ;
148- var inputType = input . GetType ( ) ;
147+ StringBuilder output = new StringBuilder ( ) ;
148+ var inputType = input . GetType ( ) ;
149149
150- if ( typeof ( IPhpObject ) . IsAssignableFrom ( inputType ) || inputType . GetCustomAttribute < PhpClass > ( ) != null ) {
151- return this . SerializeToObject ( input ) ;
152- }
150+ if ( typeof ( IPhpObject ) . IsAssignableFrom ( inputType ) || inputType . GetCustomAttribute < PhpClass > ( ) != null ) {
151+ return this . SerializeToObject ( input ) ;
152+ }
153153
154- List < MemberInfo > members = new ( ) ;
155- if ( inputType . IsValueType ) {
156- foreach ( FieldInfo field in inputType . GetFields ( ) ) {
157- if ( field . IsPublic ) {
158- var attribute = Attribute . GetCustomAttribute ( field , typeof ( PhpIgnoreAttribute ) , false ) ;
159- if ( attribute == null ) {
160- members . Add ( field ) ;
161- }
154+ List < MemberInfo > members = new ( ) ;
155+ if ( inputType . IsValueType ) {
156+ foreach ( FieldInfo field in inputType . GetFields ( ) ) {
157+ if ( field . IsPublic ) {
158+ var attribute = Attribute . GetCustomAttribute ( field , typeof ( PhpIgnoreAttribute ) , false ) ;
159+ if ( attribute == null ) {
160+ members . Add ( field ) ;
162161 }
163162 }
164- } else {
165- foreach ( PropertyInfo property in inputType . GetProperties ( ) ) {
166- if ( property . CanRead ) {
167- var ignoreAttribute = Attribute . GetCustomAttribute (
168- property ,
169- typeof ( PhpIgnoreAttribute ) ,
170- false
171- ) ;
172- if ( ignoreAttribute == null ) {
173- members . Add ( property ) ;
174- }
163+ }
164+ } else {
165+ foreach ( PropertyInfo property in inputType . GetProperties ( ) ) {
166+ if ( property . CanRead ) {
167+ var ignoreAttribute = Attribute . GetCustomAttribute (
168+ property ,
169+ typeof ( PhpIgnoreAttribute ) ,
170+ false
171+ ) ;
172+ if ( ignoreAttribute == null ) {
173+ members . Add ( property ) ;
175174 }
176175 }
177176 }
178- output . Append ( $ "a:{ members . Count } :") ;
179- output . Append ( '{' ) ;
180- foreach ( var member in members ) {
181- output . Append ( this . SerializeMember ( member , input ) ) ;
177+ }
178+ int memberCount = 0 ;
179+ StringBuilder memberData = new ( ) ;
180+ foreach ( var member in members ) {
181+ var memberString = this . SerializeMember ( member , input ) ;
182+ if ( memberString != null ) {
183+ memberData . Append ( memberString ) ;
184+ memberCount ++ ;
182185 }
183- output . Append ( '}' ) ;
184- return output . ToString ( ) ;
185186 }
187+ output . Append ( $ "a:{ memberCount } :")
188+ . Append ( '{' )
189+ . Append ( memberData )
190+ . Append ( '}' ) ;
191+ return output . ToString ( ) ;
192+ }
186193 }
187194 }
188195
@@ -211,18 +218,24 @@ private string SerializeToObject(object input) {
211218 }
212219 }
213220 }
214-
221+ int memberCount = 0 ;
222+ StringBuilder members = new StringBuilder ( ) ;
223+ foreach ( PropertyInfo property in properties ) {
224+ var memberString = this . SerializeMember ( property , input ) ;
225+ if ( memberString != null ) {
226+ members . Append ( memberString ) ;
227+ memberCount ++ ;
228+ }
229+ }
215230 output . Append ( "O:" )
216231 . Append ( className . Length )
217232 . Append ( ":\" " )
218233 . Append ( className )
219234 . Append ( "\" :" )
220235 . Append ( properties . Count )
221- . Append ( ":{" ) ;
222- foreach ( PropertyInfo property in properties ) {
223- output . Append ( this . SerializeMember ( property , input ) ) ;
224- }
225- output . Append ( '}' ) ;
236+ . Append ( ":{" )
237+ . Append ( members )
238+ . Append ( '}' ) ;
226239 return output . ToString ( ) ;
227240 }
228241
@@ -232,13 +245,18 @@ private string SerializeMember(MemberInfo member, object input) {
232245 typeof ( PhpPropertyAttribute ) ,
233246 false
234247 ) ;
235-
248+ object key ;
236249 if ( attribute != null ) {
237- if ( attribute . IsInteger == true ) {
238- return $ "{ this . Serialize ( attribute . Key ) } { this . Serialize ( member . GetValue ( input ) ) } ";
239- }
240- return $ "{ this . Serialize ( attribute . Name ) } { this . Serialize ( member . GetValue ( input ) ) } ";
250+ key = attribute . IsInteger
251+ ? attribute . Key
252+ : attribute . Name ;
253+ } else {
254+ key = member . Name ;
255+ }
256+ var filter = member . GetCustomAttribute < PhpSerializationFilter > ( ) ;
257+ if ( filter != null ) {
258+ return filter . Serialize ( key , member . GetValue ( input ) , this . _options ) ;
241259 }
242- return $ " { this . Serialize ( member . Name ) } { this . Serialize ( member . GetValue ( input ) ) } " ;
260+ return string . Concat ( this . Serialize ( key ) , this . Serialize ( member . GetValue ( input ) ) ) ;
243261 }
244262}
0 commit comments