@@ -84,7 +84,7 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
8484 final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct ) binField ;
8585 final Class <?> componentType = record .mappingField .getType ().getComponentType ();
8686
87- Object valueArray = getFieldValue (instance , record .mappingField );
87+ Object valueArray = getFieldValue (instance , record .getter , record . mappingField );
8888
8989 valueArray = valueArray == null ? Array .newInstance (componentType , structArray .size ()) : valueArray ;
9090
@@ -100,41 +100,41 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
100100 Array .set (valueArray , i , JBBPMapper .map (structArray .getElementAt (i ), curInstance , customFieldProcessor ));
101101 }
102102 }
103- setFieldValue (instance , record .mappingField , binField , valueArray );
103+ setFieldValue (instance , record .setter , record . mappingField , binField , valueArray );
104104 } else {
105105 // primitive
106- mapArrayField (instance , record .mappingField , (JBBPAbstractArrayField <?>) binField , record .binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
106+ mapArrayField (instance , record .setter , record . mappingField , (JBBPAbstractArrayField <?>) binField , record .binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
107107 }
108108 } else {
109109 throw new JBBPMapperException ("Can't map a non-array value to an array mapping field" , binField , record .mappingClass , record .mappingField , null );
110110 }
111111 };
112112 private static final FieldProcessor PROC_NUM = (record , rootStructure , instance , customFieldProcessor , binField , flags , instantiators ) -> {
113113 if (binField instanceof JBBPNumericField ) {
114- mapNumericField (instance , record .mappingField , (JBBPNumericField ) binField , record .binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
114+ mapNumericField (instance , record .setter , record . mappingField , (JBBPNumericField ) binField , record .binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
115115 } else if (binField instanceof JBBPFieldString ) {
116116 if (record .mappingField .getType ().isPrimitive ()) {
117117 throw new JBBPMapperException ("Can't map a string to a primitive mapping field" , binField , record .mappingClass , record .mappingField , null );
118118 } else {
119- setFieldValue (instance , record .mappingField , binField , ((JBBPFieldString ) binField ).getAsString ());
119+ setFieldValue (instance , record .setter , record . mappingField , binField , ((JBBPFieldString ) binField ).getAsString ());
120120 }
121121 } else if (binField instanceof JBBPFieldStruct ) {
122122 if (record .mappingField .getType ().isPrimitive ()) {
123123 throw new JBBPMapperException ("Can't map a structure to a primitive mapping field" , binField , record .mappingClass , record .mappingField , null );
124124 } else {
125- final Object curValue = getFieldValue (instance , record .mappingField );
125+ final Object curValue = getFieldValue (instance , record .getter , record . mappingField );
126126 if (curValue == null ) {
127- setFieldValue (instance , record .mappingField , binField , JBBPMapper .map ((JBBPFieldStruct ) binField , tryMakeInstance (record .mappingField .getType (), binField , instance , record .mappingField , instantiators ), customFieldProcessor ));
127+ setFieldValue (instance , record .setter , record . mappingField , binField , JBBPMapper .map ((JBBPFieldStruct ) binField , tryMakeInstance (record .mappingField .getType (), binField , instance , record .mappingField , instantiators ), customFieldProcessor ));
128128 } else {
129- setFieldValue (instance , record .mappingField , binField , JBBPMapper .map ((JBBPFieldStruct ) binField , curValue , customFieldProcessor ));
129+ setFieldValue (instance , record .setter , record . mappingField , binField , JBBPMapper .map ((JBBPFieldStruct ) binField , curValue , customFieldProcessor ));
130130 }
131131 }
132132 } else {
133133 boolean processed = false ;
134134 if (record .mappingField .getType () == String .class && binField instanceof JBBPAbstractArrayField ) {
135135 final String convertedValue = convertFieldValueToString ((JBBPAbstractArrayField <?>) binField );
136136 if (convertedValue != null ) {
137- setFieldValue (instance , record .mappingField , binField , convertedValue );
137+ setFieldValue (instance , record .setter , record . mappingField , binField , convertedValue );
138138 processed = true ;
139139 }
140140 }
@@ -146,6 +146,8 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
146146
147147 public final Field mappingField ;
148148 public final Class <?> mappingClass ;
149+ public final Method setter ;
150+ public final Method getter ;
149151 public final Bin binAnnotation ;
150152 public final boolean bitWideField ;
151153 public final String fieldName ;
@@ -155,8 +157,13 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
155157 public final FieldProcessor proc ;
156158
157159 MappedFieldRecord (final Field mappingField ,
160+ final Method setter ,
161+ final Method getter ,
158162 final Class <?> mappingClass ,
159163 final Bin binAnnotation ) {
164+ this .setter = setter ;
165+ this .getter = getter ;
166+
160167 this .mappingField = mappingField ;
161168 this .mappingClass = mappingClass ;
162169 this .binAnnotation = binAnnotation ;
@@ -190,42 +197,51 @@ public final class MappedFieldRecord implements Comparable<MappedFieldRecord> {
190197 * Map a parsed array to an array field in mapping class.
191198 *
192199 * @param mappingClassInstance a mapping class instance, must not be null
200+ * @param setter detected setter for the field, can be null
193201 * @param mappingField a field in the mapping class to be set, must not be
194202 * null
195203 * @param arrayField a binary parsed array field, must not be null
196204 * @param invertBitOrder flag shows that values of an array must be bit
197205 * reversed before set
198206 */
199- private static void mapArrayField (final Object mappingClassInstance , final Field mappingField , final JBBPAbstractArrayField <?> arrayField , final boolean invertBitOrder ) {
207+ private static void mapArrayField (final Object mappingClassInstance , final Method setter , final Field mappingField , final JBBPAbstractArrayField <?> arrayField , final boolean invertBitOrder ) {
200208 try {
209+ final Object value ;
201210 if (arrayField instanceof JBBPFieldArrayLong && mappingField .getType ().getComponentType () == double .class ) {
202211 final long [] longarray = (long []) arrayField .getValueArrayAsObject (invertBitOrder );
203212 final double [] doublearray = new double [longarray .length ];
204213 for (int i = 0 ; i < longarray .length ; i ++) {
205214 doublearray [i ] = Double .longBitsToDouble (longarray [i ]);
206215 }
207- mappingField . set ( mappingClassInstance , doublearray ) ;
216+ value = doublearray ;
208217 } else if (arrayField instanceof JBBPFieldArrayInt && mappingField .getType ().getComponentType () == float .class ) {
209218 final int [] intarray = (int []) arrayField .getValueArrayAsObject (invertBitOrder );
210219 final float [] floatarray = new float [intarray .length ];
211220 for (int i = 0 ; i < intarray .length ; i ++) {
212221 floatarray [i ] = Float .intBitsToFloat (intarray [i ]);
213222 }
214- mappingField . set ( mappingClassInstance , floatarray ) ;
223+ value = floatarray ;
215224 } else if (arrayField instanceof JBBPFieldArrayUShort && mappingField .getType ().getComponentType () == char .class ) {
216225 final short [] shortarray = (short []) arrayField .getValueArrayAsObject (invertBitOrder );
217226 final char [] chararray = new char [shortarray .length ];
218227 for (int i = 0 ; i < shortarray .length ; i ++) {
219228 chararray [i ] = (char ) shortarray [i ];
220229 }
221- mappingField .set (mappingClassInstance , chararray );
230+ value = chararray ;
231+ } else {
232+ value = arrayField .getValueArrayAsObject (invertBitOrder );
233+ }
234+ if (setter == null ) {
235+ mappingField .set (mappingClassInstance , value );
222236 } else {
223- mappingField . set (mappingClassInstance , arrayField . getValueArrayAsObject ( invertBitOrder ) );
237+ setter . invoke (mappingClassInstance , value );
224238 }
225239 } catch (IllegalAccessException ex ) {
226240 throw new JBBPMapperException ("Can't get access to a mapping field" , arrayField , mappingClassInstance .getClass (), mappingField , ex );
227241 } catch (IllegalArgumentException ex ) {
228242 throw new JBBPMapperException ("Can't set argument to a mapping field" , arrayField , mappingClassInstance .getClass (), mappingField , ex );
243+ } catch (InvocationTargetException ex ) {
244+ throw new JBBPMapperException ("Can't set argument to field through setter" , arrayField , mappingClassInstance .getClass (), mappingField , ex );
229245 }
230246 }
231247
@@ -279,38 +295,80 @@ private static String convertFieldValueToString(final JBBPAbstractArrayField<?>
279295 * class.
280296 *
281297 * @param mappingClassInstance the mapping class instance, must not be null
298+ * @param setter detected setter for field, can be null
282299 * @param mappingField a mapping field to set the value, must not be null
283300 * @param numericField a parsed numeric field which value should be used, must
284301 * not be null
285302 * @param invertBitOrder flag shows that the parsed numeric field value must
286303 * be reversed in its bit before setting
287304 */
288- private static void mapNumericField (final Object mappingClassInstance , final Field mappingField , final JBBPNumericField numericField , final boolean invertBitOrder ) {
305+ private static void mapNumericField (final Object mappingClassInstance , final Method setter , final Field mappingField , final JBBPNumericField numericField , final boolean invertBitOrder ) {
289306 final Class <?> fieldClass = mappingField .getType ();
290307 try {
291308 if (fieldClass == byte .class ) {
292- mappingField .setByte (mappingClassInstance , (byte ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ()));
309+ final byte value = (byte ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ());
310+ if (setter == null ) {
311+ mappingField .setByte (mappingClassInstance , value );
312+ } else {
313+ setter .invoke (mappingClassInstance , value );
314+ }
293315 } else if (fieldClass == boolean .class ) {
294- mappingField .setBoolean (mappingClassInstance , numericField .getAsBool ());
316+ if (setter == null ) {
317+ mappingField .setBoolean (mappingClassInstance , numericField .getAsBool ());
318+ } else {
319+ setter .invoke (mappingClassInstance , numericField .getAsBool ());
320+ }
295321 } else if (fieldClass == char .class ) {
296- mappingField .setChar (mappingClassInstance , (char ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ()));
322+ final char value = (char ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ());
323+ if (setter == null ) {
324+ mappingField .setChar (mappingClassInstance , value );
325+ } else {
326+ setter .invoke (mappingClassInstance , value );
327+ }
297328 } else if (fieldClass == short .class ) {
298- mappingField .setShort (mappingClassInstance , (short ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ()));
329+ final short value = (short ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ());
330+ if (setter == null ) {
331+ mappingField .setShort (mappingClassInstance , value );
332+ } else {
333+ setter .invoke (mappingClassInstance , value );
334+ }
299335 } else if (fieldClass == int .class ) {
300- mappingField .setInt (mappingClassInstance , (int ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ()));
336+ final int value = (int ) (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsInt ());
337+ if (setter == null ) {
338+ mappingField .setInt (mappingClassInstance , value );
339+ } else {
340+ setter .invoke (mappingClassInstance , value );
341+ }
301342 } else if (fieldClass == long .class ) {
302- mappingField .setLong (mappingClassInstance , (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsLong ()));
343+ final long value = (invertBitOrder ? numericField .getAsInvertedBitOrder () : numericField .getAsLong ());
344+ if (setter == null ) {
345+ mappingField .setLong (mappingClassInstance , value );
346+ } else {
347+ setter .invoke (mappingClassInstance , value );
348+ }
303349 } else if (fieldClass == float .class ) {
350+ final float value ;
304351 if (numericField instanceof JBBPFieldInt ) {
305- mappingField . setFloat ( mappingClassInstance , invertBitOrder ? Float .intBitsToFloat ((int ) numericField .getAsInvertedBitOrder ()) : Float .intBitsToFloat (numericField .getAsInt () ));
352+ value = invertBitOrder ? Float .intBitsToFloat ((int ) numericField .getAsInvertedBitOrder ()) : Float .intBitsToFloat (numericField .getAsInt ());
306353 } else {
307- mappingField .setFloat (mappingClassInstance , invertBitOrder ? Float .intBitsToFloat ((int ) numericField .getAsInvertedBitOrder ()) : numericField .getAsFloat ());
354+ value = invertBitOrder ? Float .intBitsToFloat ((int ) numericField .getAsInvertedBitOrder ()) : numericField .getAsFloat ();
355+ }
356+ if (setter == null ) {
357+ mappingField .setFloat (mappingClassInstance , value );
358+ } else {
359+ setter .invoke (mappingClassInstance , value );
308360 }
309361 } else if (fieldClass == double .class ) {
362+ final double value ;
310363 if (numericField instanceof JBBPFieldLong ) {
311- mappingField .setDouble (mappingClassInstance , invertBitOrder ? Double .longBitsToDouble (numericField .getAsInvertedBitOrder ()) : Double .longBitsToDouble (numericField .getAsLong ()));
364+ value = invertBitOrder ? Double .longBitsToDouble (numericField .getAsInvertedBitOrder ()) : Double .longBitsToDouble (numericField .getAsLong ());
365+ } else {
366+ value = invertBitOrder ? Double .longBitsToDouble (numericField .getAsInvertedBitOrder ()) : numericField .getAsDouble ();
367+ }
368+ if (setter == null ) {
369+ mappingField .setDouble (mappingClassInstance , value );
312370 } else {
313- mappingField . setDouble (mappingClassInstance , invertBitOrder ? Double . longBitsToDouble ( numericField . getAsInvertedBitOrder ()) : numericField . getAsDouble () );
371+ setter . invoke (mappingClassInstance , value );
314372 }
315373 } else {
316374 throw new JBBPMapperException ("Unsupported mapping class field type to be mapped for binary parsed data" , (JBBPAbstractField ) numericField , mappingClassInstance .getClass (), mappingField , null );
@@ -319,24 +377,33 @@ private static void mapNumericField(final Object mappingClassInstance, final Fie
319377 throw new JBBPMapperException ("Can't get access to a mapping field" , (JBBPAbstractField ) numericField , mappingClassInstance .getClass (), mappingField , ex );
320378 } catch (IllegalArgumentException ex ) {
321379 throw new JBBPMapperException ("Can't set argument to a mapping field" , (JBBPAbstractField ) numericField , mappingClassInstance .getClass (), mappingField , ex );
380+ } catch (InvocationTargetException ex ) {
381+ throw new JBBPMapperException ("Can't set argument to a mapping field through setter" , (JBBPAbstractField ) numericField , mappingClassInstance .getClass (), mappingField , ex );
322382 }
323383 }
324384
325385 /**
326386 * Get a value of a field from a class instance.
327387 *
328388 * @param classInstance a class instance object
389+ * @param getter method to get field value, can be null
329390 * @param classField a class field which value must be returned, must not be
330391 * null
331392 * @return the field value for the class instance
332393 */
333- private static Object getFieldValue (final Object classInstance , final Field classField ) {
394+ private static Object getFieldValue (final Object classInstance , final Method getter , final Field classField ) {
334395 try {
335- return classField .get (classInstance );
396+ if (getter == null )
397+ return classField .get (classInstance );
398+ else {
399+ return getter .invoke (classInstance );
400+ }
336401 } catch (IllegalArgumentException ex ) {
337402 throw new JBBPMapperException ("Can't set get value from a mapping field" , null , classInstance .getClass (), classField , ex );
338403 } catch (IllegalAccessException ex ) {
339404 throw new JBBPMapperException ("Can't get access to a mapping field" , null , classInstance .getClass (), classField , ex );
405+ } catch (InvocationTargetException ex ) {
406+ throw new JBBPMapperException ("Can't get field value through getter" , null , classInstance .getClass (), classField , ex );
340407 }
341408 }
342409
@@ -345,18 +412,25 @@ private static Object getFieldValue(final Object classInstance, final Field clas
345412 * fields!
346413 *
347414 * @param classInstance a class instance
415+ * @param setter setter for the field, can be null
348416 * @param classField a mapping class field which should be set by the value,
349417 * must not be null
350418 * @param binField a parsed bin field which value will be set, can be null
351419 * @param value a value to be set to the class field
352420 */
353- static void setFieldValue (final Object classInstance , final Field classField , final JBBPAbstractField binField , final Object value ) {
421+ static void setFieldValue (final Object classInstance , final Method setter , final Field classField , final JBBPAbstractField binField , final Object value ) {
354422 try {
355- classField .set (classInstance , value );
423+ if (setter == null )
424+ classField .set (classInstance , value );
425+ else {
426+ setter .invoke (classInstance , value );
427+ }
356428 } catch (IllegalArgumentException ex ) {
357429 throw new JBBPMapperException ("Can't set value to a mapping field" , binField , classInstance .getClass (), classField , ex );
358430 } catch (IllegalAccessException ex ) {
359431 throw new JBBPMapperException ("Can't get access to a mapping field" , binField , classInstance .getClass (), classField , ex );
432+ } catch (InvocationTargetException ex ) {
433+ throw new JBBPMapperException ("Can't set field value through setter" , binField , classInstance .getClass (), classField , ex );
360434 }
361435 }
362436
0 commit comments