@@ -269,6 +269,130 @@ public static <T> T map(final JBBPFieldStruct rootStructure, final T instance, f
269269 return map (rootStructure , instance , customFieldProcessor , 0 , instantiators );
270270 }
271271
272+ @ SafeVarargs
273+ @ SuppressWarnings ("varargs" )
274+ private static void processFieldOfMappedClass (
275+ final Field mappingField ,
276+ final Class <?> mappingClass ,
277+ final Bin binAnnotation ,
278+ final JBBPFieldStruct rootStructure ,
279+ final Object instance ,
280+ final JBBPMapperCustomFieldProcessor customFieldProcessor ,
281+ final int flags ,
282+ final Function <Class <?>, Object >... instantiators
283+ ) {
284+ if (binAnnotation .custom ()) {
285+ JBBPUtils .assertNotNull (customFieldProcessor , "There is a custom mapping field, in the case you must provide a custom mapping field processor" );
286+ final Object value = customFieldProcessor .prepareObjectForMapping (rootStructure , binAnnotation , mappingField );
287+ setFieldValue (instance , mappingField , null , value );
288+ } else {
289+ final BinType fieldType ;
290+
291+ final JBBPBitNumber mappedBitNumber = binAnnotation .outBitNumber ();
292+
293+ if (binAnnotation .type () == BinType .UNDEFINED ) {
294+ BinType thetype = BinType .findCompatible (mappingField .getType ());
295+ if (thetype == null ) {
296+ throw new JBBPMapperException ("Can't find compatible type for a mapping field" , rootStructure , mappingClass , mappingField , null );
297+ } else if (mappedBitNumber .getBitNumber () < 8 && !(thetype == BinType .STRUCT || thetype == BinType .STRUCT_ARRAY )) {
298+ thetype = thetype .isArray () ? BinType .BIT_ARRAY : BinType .BIT ;
299+ }
300+ fieldType = thetype ;
301+ } else {
302+ fieldType = binAnnotation .type ();
303+ }
304+ final boolean bitWideField = fieldType == BinType .BIT || fieldType == BinType .BIT_ARRAY ;
305+
306+ final String fieldName = binAnnotation .name ().length () == 0 ? mappingField .getName () : binAnnotation .name ();
307+ final String fieldPath = binAnnotation .path ();
308+
309+ final JBBPAbstractField binField ;
310+
311+ if (fieldPath .length () == 0 ) {
312+ binField = fieldName .length () == 0 ? rootStructure .findFieldForType (fieldType .getFieldClass ()) : rootStructure .findFieldForNameAndType (fieldName , fieldType .getFieldClass ());
313+ } else {
314+ binField = rootStructure .findFieldForPathAndType (fieldPath , fieldType .getFieldClass ());
315+ }
316+
317+ if (binField == null ) {
318+ if ((flags & FLAG_IGNORE_MISSING_VALUES ) != 0 ) {
319+ return ;
320+ }
321+ throw new JBBPMapperException ("Can't find value to be mapped to a mapping field [" + mappingField + ']' , null , mappingClass , mappingField , null );
322+ }
323+
324+ if (bitWideField && mappedBitNumber != JBBPBitNumber .BITS_8 && ((BitEntity ) binField ).getBitWidth () != mappedBitNumber ) {
325+ throw new JBBPMapperException ("Can't map value to a mapping field for different field bit width [" + mappedBitNumber + "!=" + ((BitEntity ) binField ).getBitWidth ().getBitNumber () + ']' , null , mappingClass , mappingField , null );
326+ }
327+
328+ if (mappingField .getType ().isArray ()) {
329+ if (binField instanceof JBBPAbstractArrayField ) {
330+ if (binField instanceof JBBPFieldArrayStruct ) {
331+ // structure
332+ final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct ) binField ;
333+ final Class <?> componentType = mappingField .getType ().getComponentType ();
334+
335+ Object valueArray = getFieldValue (instance , mappingField );
336+
337+ valueArray = valueArray == null ? Array .newInstance (componentType , structArray .size ()) : valueArray ;
338+
339+ if (Array .getLength (valueArray ) != structArray .size ()) {
340+ throw new JBBPMapperException ("Can't map an array field for different expected size [" + Array .getLength (valueArray ) + "!=" + structArray .size () + ']' , binField , mappingClass , mappingField , null );
341+ }
342+
343+ for (int i = 0 ; i < structArray .size (); i ++) {
344+ final Object curInstance = Array .get (valueArray , i );
345+ if (curInstance == null ) {
346+ Array .set (valueArray , i , map (structArray .getElementAt (i ), tryMakeInstance (componentType , binField , instance , mappingField , instantiators ), customFieldProcessor , instantiators ));
347+ } else {
348+ Array .set (valueArray , i , map (structArray .getElementAt (i ), curInstance , customFieldProcessor ));
349+ }
350+ }
351+ setFieldValue (instance , mappingField , binField , valueArray );
352+ } else {
353+ // primitive
354+ mapArrayField (instance , mappingField , (JBBPAbstractArrayField <?>) binField , binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
355+ }
356+ } else {
357+ throw new JBBPMapperException ("Can't map a non-array value to an array mapping field" , binField , mappingClass , mappingField , null );
358+ }
359+ } else {
360+ if (binField instanceof JBBPNumericField ) {
361+ mapNumericField (instance , mappingField , (JBBPNumericField ) binField , binAnnotation .bitOrder () == JBBPBitOrder .MSB0 );
362+ } else if (binField instanceof JBBPFieldString ) {
363+ if (mappingField .getType ().isPrimitive ()) {
364+ throw new JBBPMapperException ("Can't map a string to a primitive mapping field" , binField , mappingClass , mappingField , null );
365+ } else {
366+ setFieldValue (instance , mappingField , binField , ((JBBPFieldString ) binField ).getAsString ());
367+ }
368+ } else if (binField instanceof JBBPFieldStruct ) {
369+ if (mappingField .getType ().isPrimitive ()) {
370+ throw new JBBPMapperException ("Can't map a structure to a primitive mapping field" , binField , mappingClass , mappingField , null );
371+ } else {
372+ final Object curValue = getFieldValue (instance , mappingField );
373+ if (curValue == null ) {
374+ setFieldValue (instance , mappingField , binField , map ((JBBPFieldStruct ) binField , tryMakeInstance (mappingField .getType (), binField , instance , mappingField , instantiators ), customFieldProcessor ));
375+ } else {
376+ setFieldValue (instance , mappingField , binField , map ((JBBPFieldStruct ) binField , curValue , customFieldProcessor ));
377+ }
378+ }
379+ } else {
380+ boolean processed = false ;
381+ if (mappingField .getType () == String .class && binField instanceof JBBPAbstractArrayField ) {
382+ final String convertedValue = convertFieldValueToString ((JBBPAbstractArrayField <?>) binField );
383+ if (convertedValue != null ) {
384+ setFieldValue (instance , mappingField , binField , convertedValue );
385+ processed = true ;
386+ }
387+ }
388+ if (!processed ) {
389+ throw new JBBPMapperException ("Can't map a field for its value incompatibility" , binField , mappingClass , mappingField , null );
390+ }
391+ }
392+ }
393+ }
394+ }
395+
272396 /**
273397 * Map a structure to a class instance.
274398 *
@@ -324,116 +448,16 @@ public static <T> T map(final JBBPFieldStruct rootStructure, final T instance, f
324448 }
325449 mappedAnno = fieldAnno == null ? defaultAnno : fieldAnno ;
326450
327- if (mappedAnno .custom ()) {
328- JBBPUtils .assertNotNull (customFieldProcessor , "There is a custom mapping field, in the case you must provide a custom mapping field processor" );
329- final Object value = customFieldProcessor .prepareObjectForMapping (rootStructure , mappedAnno , mappingField );
330- setFieldValue (instance , mappingField , null , value );
331- } else {
332- final BinType fieldType ;
333-
334- final JBBPBitNumber mappedBitNumber = mappedAnno .outBitNumber ();
335-
336- if (mappedAnno .type () == BinType .UNDEFINED ) {
337- BinType thetype = BinType .findCompatible (mappingField .getType ());
338- if (thetype == null ) {
339- throw new JBBPMapperException ("Can't find compatible type for a mapping field" , rootStructure , mappingClass , mappingField , null );
340- } else if (mappedBitNumber .getBitNumber () < 8 && !(thetype == BinType .STRUCT || thetype == BinType .STRUCT_ARRAY )) {
341- thetype = thetype .isArray () ? BinType .BIT_ARRAY : BinType .BIT ;
342- }
343- fieldType = thetype ;
344- } else {
345- fieldType = mappedAnno .type ();
346- }
347- final boolean bitWideField = fieldType == BinType .BIT || fieldType == BinType .BIT_ARRAY ;
348-
349- final String fieldName = mappedAnno .name ().length () == 0 ? mappingField .getName () : mappedAnno .name ();
350- final String fieldPath = mappedAnno .path ();
351-
352- final JBBPAbstractField binField ;
353-
354- if (fieldPath .length () == 0 ) {
355- binField = fieldName .length () == 0 ? rootStructure .findFieldForType (fieldType .getFieldClass ()) : rootStructure .findFieldForNameAndType (fieldName , fieldType .getFieldClass ());
356- } else {
357- binField = rootStructure .findFieldForPathAndType (fieldPath , fieldType .getFieldClass ());
358- }
359-
360- if (binField == null ) {
361- if ((flags & FLAG_IGNORE_MISSING_VALUES ) != 0 ) {
362- continue ;
363- }
364- throw new JBBPMapperException ("Can't find value to be mapped to a mapping field [" + mappingField + ']' , null , mappingClass , mappingField , null );
365- }
366-
367- if (bitWideField && mappedBitNumber != JBBPBitNumber .BITS_8 && ((BitEntity ) binField ).getBitWidth () != mappedBitNumber ) {
368- throw new JBBPMapperException ("Can't map value to a mapping field for different field bit width [" + mappedBitNumber + "!=" + ((BitEntity ) binField ).getBitWidth ().getBitNumber () + ']' , null , mappingClass , mappingField , null );
369- }
370-
371- if (mappingField .getType ().isArray ()) {
372- if (binField instanceof JBBPAbstractArrayField ) {
373- if (binField instanceof JBBPFieldArrayStruct ) {
374- // structure
375- final JBBPFieldArrayStruct structArray = (JBBPFieldArrayStruct ) binField ;
376- final Class <?> componentType = mappingField .getType ().getComponentType ();
377-
378- Object valueArray = getFieldValue (instance , mappingField );
379-
380- valueArray = valueArray == null ? Array .newInstance (componentType , structArray .size ()) : valueArray ;
381-
382- if (Array .getLength (valueArray ) != structArray .size ()) {
383- throw new JBBPMapperException ("Can't map an array field for different expected size [" + Array .getLength (valueArray ) + "!=" + structArray .size () + ']' , binField , mappingClass , mappingField , null );
384- }
385-
386- for (int i = 0 ; i < structArray .size (); i ++) {
387- final Object curInstance = Array .get (valueArray , i );
388- if (curInstance == null ) {
389- Array .set (valueArray , i , map (structArray .getElementAt (i ), tryMakeInstance (componentType , binField , instance , mappingField , instantiators ), customFieldProcessor , instantiators ));
390- } else {
391- Array .set (valueArray , i , map (structArray .getElementAt (i ), curInstance , customFieldProcessor ));
392- }
393- }
394- setFieldValue (instance , mappingField , binField , valueArray );
395- } else {
396- // primitive
397- mapArrayField (instance , mappingField , (JBBPAbstractArrayField <?>) binField , mappedAnno .bitOrder () == JBBPBitOrder .MSB0 );
398- }
399- } else {
400- throw new JBBPMapperException ("Can't map a non-array value to an array mapping field" , binField , mappingClass , mappingField , null );
401- }
402- } else {
403- if (binField instanceof JBBPNumericField ) {
404- mapNumericField (instance , mappingField , (JBBPNumericField ) binField , mappedAnno .bitOrder () == JBBPBitOrder .MSB0 );
405- } else if (binField instanceof JBBPFieldString ) {
406- if (mappingField .getType ().isPrimitive ()) {
407- throw new JBBPMapperException ("Can't map a string to a primitive mapping field" , binField , mappingClass , mappingField , null );
408- } else {
409- setFieldValue (instance , mappingField , binField , ((JBBPFieldString ) binField ).getAsString ());
410- }
411- } else if (binField instanceof JBBPFieldStruct ) {
412- if (mappingField .getType ().isPrimitive ()) {
413- throw new JBBPMapperException ("Can't map a structure to a primitive mapping field" , binField , mappingClass , mappingField , null );
414- } else {
415- final Object curValue = getFieldValue (instance , mappingField );
416- if (curValue == null ) {
417- setFieldValue (instance , mappingField , binField , map ((JBBPFieldStruct ) binField , tryMakeInstance (mappingField .getType (), binField , instance , mappingField , instantiators ), customFieldProcessor ));
418- } else {
419- setFieldValue (instance , mappingField , binField , map ((JBBPFieldStruct ) binField , curValue , customFieldProcessor ));
420- }
421- }
422- } else {
423- boolean processed = false ;
424- if (mappingField .getType () == String .class && binField instanceof JBBPAbstractArrayField ) {
425- final String convertedValue = convertFieldValueToString ((JBBPAbstractArrayField <?>) binField );
426- if (convertedValue != null ) {
427- setFieldValue (instance , mappingField , binField , convertedValue );
428- processed = true ;
429- }
430- }
431- if (!processed ) {
432- throw new JBBPMapperException ("Can't map a field for its value incompatibility" , binField , mappingClass , mappingField , null );
433- }
434- }
435- }
436- }
451+ processFieldOfMappedClass (
452+ mappingField ,
453+ mappingClass ,
454+ mappedAnno ,
455+ rootStructure ,
456+ instance ,
457+ customFieldProcessor ,
458+ flags ,
459+ instantiators
460+ );
437461 }
438462 }
439463 return instance ;
0 commit comments