private ContentData matchBytes ( byte [ ] bytes , int prevOffset , int level , ContentData contentData ) { int offset = this . offset ; if ( offsetInfo != null ) { // offset can be null if we run out of bytes Integer maybeOffset = offsetInfo . getOffset ( bytes ) ; if ( maybeOffset == null ) { return null ; } offset = maybeOffset ; } if ( addOffset ) { offset = prevOffset + offset ; } boolean required = ( testValue == null && formatter != null ) ; Object val = matcher . extractValueFromBytes ( offset , bytes , required ) ; if ( val == null ) { return null ; } if ( testValue != null ) { MutableOffset mutableOffset = new MutableOffset ( offset ) ; val = matcher . isMatch ( testValue , andValue , unsignedType , val , mutableOffset , bytes ) ; if ( val == null ) { return null ; } offset = mutableOffset . offset ; } if ( contentData == null ) { contentData = new ContentData ( name , mimeType , level ) ; // default is a child didn't match, set a partial so the matcher will keep looking contentData . partial = true ; } if ( formatter != null ) { if ( clearFormat ) { contentData . sb . setLength ( 0 ) ; } // if we are appending and need a space then prepend one if ( formatSpacePrefix && contentData . sb . length ( ) > 0 ) { contentData . sb . append ( ' ' ) ; } matcher . renderValue ( contentData . sb , val , formatter ) ; } logger . trace ( "matched data: {}: {}" , this , contentData ) ; if ( children == null ) { // no children so we have a full match and can set partial to false contentData . partial = false ; } else { // run through the children to add more content-type details boolean allOptional = true ; for ( MagicEntry entry : children ) { if ( ! entry . isOptional ( ) ) { allOptional = false ; } // goes recursive here entry . matchBytes ( bytes , offset , level + 1 , contentData ) ; // we continue to match to see if we can add additional children info to the name } if ( allOptional ) { contentData . partial = false ; } } /* * Now that we have processed this entry (either with or without children), see if we still need to annotate the * content information. * * NOTE: the children will have the first opportunity to set this which makes sense since they are the most * specific. */ if ( name != MagicEntryParser . UNKNOWN_NAME && contentData . name == MagicEntryParser . UNKNOWN_NAME ) { contentData . name = name ; } /* * Set the mime-type if it is not set already or if we've gotten more specific in the processing of a pattern * and determine that it's actually a different type so we can override the previous mime-type. Example of this * is Adobe Illustrator which looks like a PDF but has extra stuff in it. */ if ( mimeType != null && ( contentData . mimeType == null || level > contentData . mimeTypeLevel ) ) { contentData . mimeType = mimeType ; contentData . mimeTypeLevel = level ; } return contentData ; }
Main processing method which can go recursive .