Ejemplo n.º 1
0
        private byte[] FetchMultiPacketResponse(IByteReader byteReader)
        {
            var firstResponse = new MultiPacketResponse {
                Id = byteReader.GetLong(), Total = byteReader.GetByte(), Number = byteReader.GetByte(), Size = byteReader.GetShort(), Payload = byteReader.GetRemaining()
            };

            var compressed = (firstResponse.Id & 2147483648) == 2147483648; // Check for compression

            var responses = new List <MultiPacketResponse>(new[] { firstResponse });

            for (int i = 1; i < firstResponse.Total; i++)
            {
                var response = m_udpClient.Receive(ref m_endPoint);
                var multiResponseByteReader = response.GetByteReader();
                var header = multiResponseByteReader.GetLong();
                if (header != Constants.MultiPacketResponseHeader)
                {
                    i--;
                    continue;
                }
                var id = multiResponseByteReader.GetLong();
                if (id != firstResponse.Id)
                {
                    i--;
                    continue;
                }
                responses.Add(new MultiPacketResponse {
                    Id = id, Total = multiResponseByteReader.GetByte(), Number = multiResponseByteReader.GetByte(), Size = multiResponseByteReader.GetShort(), Payload = multiResponseByteReader.GetRemaining()
                });
            }

            var assembledPayload           = AssembleResponses(responses);
            var assembledPayloadByteReader = assembledPayload.GetByteReader();

            if (compressed)
            {
                throw new NotImplementedException("Compressed responses are not yet implemented");
            }

            var payloadHeader = assembledPayloadByteReader.GetLong();

            return(assembledPayloadByteReader.GetRemaining());
        }
Ejemplo n.º 2
0
        public int ReadInt32()
        {
            int bits, value = _bytes.GetByte();

            if (value < 0x80)
            {
                return(value);
            }

            int shiftBits = 7;

            value &= 0x7f;
            do
            {
                bits = _bytes.GetByte();
                if (shiftBits < 31)
                {
                    value     |= (bits & 0x7F) << shiftBits;
                    shiftBits += 7;
                }
            }while (bits > 0x7F);
            return(value);
        }
    /**
     * Determines whether or not a given portion of a binary file matches the sequence of bytes we specify.
     *
     * @param file       The file we're currently testing
     * @param startPos   The position of the first byte in the file to examine
     * @param direction  +1 (left to right) or -1 (right to left).  The overall direction which our caller is searching in
     * @param bigEndian  True iff the signature we are matching is big-endian
     * @return true iff the portion matches
     *
     * Note: In an ideal world, we would hold bigEndian as a private member, set up on construction.  However, the framework
     *       used during parsing of the XML file does not lend itself to easily fetching information from a grandparent
     *       element.  Consequently, we parse the byte sequence specifier in ignorance of its endianness, and wait until
     *       we try to match against a specific byte sequence (here) to find out how minSeq and maxSeq should be interpreted.
     */
    public bool matchesByteSequence(IByteReader file, long startPos, int direction, bool bigEndian)
    {
        try {
            // We have to perform the comparison from big-end to little-end.  Consequently, if we're reading
            // from right to left but using big-endian-ness, or if we're reading from left-to-right but using
            // little-endian-ness, we have to search through our sequence backwards -- that is, left-to-right
            // in the former case, or right-to-left in the latter.
            if (!bigEndian && direction == 1) {
                direction = -1;
                startPos += this.getNumBytes() - 1;
            } else if (bigEndian && direction == -1) {
                direction = 1;
                startPos = startPos - this.getNumBytes() + 1;
            }
            int arrayPos = (direction == 1) ? 0 : this.getNumBytes() - 1;
            
            // Loop through the sequence, checking to ensure that the contents of the binary file >= the minimum sequence
            for (int fileOffset = 0; 0 <= arrayPos && arrayPos < this.getNumBytes(); fileOffset+=direction, arrayPos+=direction) {
                // Read the corresponding byte from the file.  Because this is stored in 2s complement form, we need to
                // convert it to the same form that minSeq is stored in
                int fileByte = file.GetByte(startPos + fileOffset);
                if (fileByte < 0) {fileByte += 256;}
                fileByte += byte.MinValue;
                
                if (fileByte < minSeq[arrayPos]) {
                    // We're outside the allowed range.
                    return negate;
                } else if (fileByte > minSeq[arrayPos])
					{
                    // The whole of the sequence is definitely greater than minSeq.  Go on and see if it's less than maxSeq.
						break;
					}
				}
            
				// Repeat the previous loop, but this time checking to ensure that the contents of the binary file <= the maximum sequence
				arrayPos = (direction == 1) ? 0 : this.getNumBytes() - 1;
				
				for (int fileOffset = 0; arrayPos >= 0 && arrayPos < this.getNumBytes(); fileOffset+=direction, arrayPos+=direction)
				{
					int fileByte = file.GetByte(startPos + fileOffset);
					if (fileByte < 0) {fileByte += 256;}
					fileByte += byte.MinValue;
                
					if (fileByte > maxSeq[arrayPos])
					{
						return negate;
					}
					else if (fileByte < maxSeq[arrayPos])
					{
						break;
					}
				}
				return !negate;
			}
			catch(Exception)
			{
				// This is most likely to occur if we run off the end of the file.  (In practice, this method shouldn't be called
				// unless we have enough bytes to read, but this is belt and braces.)
				return false;
			}
		}
Ejemplo n.º 4
0
		/**
		 * Searches for this subsequence at the start of the current file.
		 * Moves the file marker to the end of this subsequence.
		 *
		 * @param targetFile   the binary file to be identified
		 * @param reverseOrder  true if file is being searched from right to left
		 * @param bigEndian    True iff our parent signature is big-endian
		 */
		public bool isFoundAtStartOfFile(IByteReader targetFile, bool reverseOrder, bool bigEndian)
		{
			int searchDirection = reverseOrder ? -1 : 1;
			int minSeqOffset = this.getMinSeqOffset();
			int maxSeqOffset = this.getMaxSeqOffset();
			long[] startPosInFile = new long[1];
			startPosInFile[0] = reverseOrder ? targetFile.GetNumberOfBytes() - minSeqOffset - 1 : minSeqOffset;
			bool subseqFound = true;
			bool leftFrag = true;

			if (reverseOrder) { leftFrag = false; }

			//match intial fragment
			if (reverseOrder)
			{
				startPosInFile = bytePosForRightFragments(targetFile, 0, startPosInFile[0], -1, (maxSeqOffset - minSeqOffset), bigEndian);
			}
			else
			{
				startPosInFile = bytePosForLeftFragments(targetFile, startPosInFile[0], targetFile.GetNumberOfBytes() - 1, 1, (maxSeqOffset - minSeqOffset), bigEndian);
			}
			int numOptions = startPosInFile.Length;
			if (numOptions == 0)
			{
				subseqFound = false;
			}
			else
			{
				for (int i = 0; i < numOptions; i++)
				{
					startPosInFile[i] += (long)searchDirection;
				}
			}

			//match main sequence
			if (subseqFound)
			{
				//move startPosInFile according to min offset of last fragment looked at
				int minOffset = 0;
				int maxOffset = 0;
				if (this.getNumFragmentPositions(leftFrag) > 0)
				{
					minOffset = this.getFragment(leftFrag, 1, 0).getMinOffset();
					maxOffset = this.getFragment(leftFrag, 1, 0).getMaxOffset();
					for (int i = 0; i < numOptions; i++)
					{
						startPosInFile[i] += (long)(minOffset * searchDirection);
					}
				}

				//add new possible values for startPosInFile to allow for difference between maxOffset and minOffset
				int offsetRange = maxOffset - minOffset;
				if (offsetRange > 0)
				{
					long[] newStartPosInFile = new long[numOptions * (offsetRange + 1)];
					for (int i = 0; i <= offsetRange; i++)
					{
						for (int j = 0; j < numOptions; j++)
						{
							newStartPosInFile[j + i * numOptions] = startPosInFile[j] + (long)(i * searchDirection);
						}
					}
					//Arrays.sort(newStartPosInFile);
					System.Array.Sort(newStartPosInFile);
					
					int newNumOptions = 1;
					for (int i = 1; i < numOptions * (offsetRange + 1); i++)
					{
						if (newStartPosInFile[i] > newStartPosInFile[newNumOptions - 1])
						{
							newStartPosInFile[newNumOptions] = newStartPosInFile[i];
							newNumOptions++;
						}
					}
					//now copy these back to the startPosInFile array (sorted in searchDirection)
					numOptions = newNumOptions;
					if (searchDirection > 1)
					{
						System.Array.Copy(newStartPosInFile, 0, startPosInFile, 0, numOptions);						
					}
					else
					{
						//reverse order copy
						for (int i = 0; i < numOptions; i++)
						{
							startPosInFile[i] = newStartPosInFile[numOptions - 1 - i];
						}
					}

				}

				//check that the end of the file is not going to be reached
				int numSeqBytes = this.getNumBytes();
				long numBytesInFile = targetFile.GetNumberOfBytes();
				if (reverseOrder)
				{
					//cutoff if startPosInFile is too close to start of file
					for (int i = 0; i < numOptions; i++)
					{
						if (startPosInFile[i] < ((long)numSeqBytes - 1L))
						{
							numOptions = i;
						}
					}
				}
				else
				{
					//cutoff if startPosInFile is too close to end of file
					for (int i = 0; i < numOptions; i++)
					{
						if (startPosInFile[i] > (numBytesInFile - (long)numSeqBytes))
						{
							numOptions = i;
						}
					}
				}

				/*
				long refNumTries = (long)(maxOffset - minOffset) + 1L;  //this is the expected number of attempts to get a match
				//correct the number of attempts for each starting position depending on whether the end of the file may be reached
				long[] maxNumTries = new long[numOptions];
				if(reverseOrder) {
					 for(int i=0; i<numOptions; i++) {
						 long tempNumTries = (startPosInFile[i]+1L) - (long)numSeqBytes + 1L;
						 maxNumTries[i] = tempNumTries<refNumTries ? tempNumTries : refNumTries;
					 }
				} else {
					for(int i=0; i<numOptions; i++) {
						long tempNumTries = (numBytesInFile - startPosInFile[i]) - numSeqBytes + 1L;
						 maxNumTries[i] = tempNumTries<refNumTries ? tempNumTries : refNumTries;
					}
				}
				 */

				for (int iOption = 0; iOption < numOptions; iOption++)
				{
					//compare sequence with file contents directly at fileMarker position
					int byteLoopStart = reverseOrder ? numSeqBytes - 1 : 0;
					int byteLoopEnd = reverseOrder ? 0 : numSeqBytes - 1;
					long tempFileMarker = startPosInFile[iOption];
					bool provSeqMatch = true;

					//check whether the file and signature sequences match
					for (int iByte = byteLoopStart; (provSeqMatch) && (iByte <= numSeqBytes - 1) && (iByte >= 0); iByte += searchDirection)
					{
						provSeqMatch = (byteSequence[iByte] == targetFile.GetByte(tempFileMarker));
						tempFileMarker += searchDirection;
					}

					if (!provSeqMatch)
					{
						//no match
						startPosInFile[iOption] = -2L;
					}
					else
					{
						//success: a match was found - update the startPosInFile
						startPosInFile[iOption] = tempFileMarker;
					}
				}


				//check the startPosInFile array: remove -2 values, reorder and remove duplicates
				System.Array.Sort(startPosInFile, 0, numOptions);
				int newNumOptions2 = 0;
				long[] newStartPosInFile2 = new long[numOptions];
				if (numOptions > 0)
				{
					if (startPosInFile[0] >= -1L)
					{
						newStartPosInFile2[0] = startPosInFile[0];
						newNumOptions2 = 1;
					}
				}
				for (int i = 1; i < numOptions; i++)
				{
					if (startPosInFile[i] > startPosInFile[i - 1])
					{
						newStartPosInFile2[newNumOptions2] = startPosInFile[i];
						newNumOptions2++;
					}
				}

				if (newNumOptions2 == 0)
				{
					subseqFound = false;
				}
				else
				{
					numOptions = newNumOptions2;
					if (searchDirection < 0)
					{
						//for right to left search direction, reorder in reverse
						for (int iOption = 0; iOption < numOptions; iOption++)
						{
							startPosInFile[iOption] = newStartPosInFile2[numOptions - 1 - iOption];
						}
					}
					else
					{
						//for left to right search direction, copy over as is
						System.Array.Copy(newStartPosInFile2, 0, startPosInFile, 0, numOptions);
					}
				}
			}


			//match remaining sequence fragment
			long newValueStartPosInFile = 0L;
			if (subseqFound)
			{

				long[] newArrayStartPosInFile;
				if (reverseOrder)
				{
					int i = 0;
					subseqFound = false;
					while (i < numOptions && !subseqFound)
					{
						newArrayStartPosInFile = bytePosForLeftFragments(targetFile, 0L, startPosInFile[i], -1, 0, bigEndian);
						if (newArrayStartPosInFile.Length == 0)
						{
							subseqFound = false;
						}
						else
						{
							subseqFound = true;
							newValueStartPosInFile = newArrayStartPosInFile[0] - 1L;  //take away -1???
						}
						i++;
					}
				}
				else
				{
					int i = 0;
					subseqFound = false;
					while (i < numOptions && !subseqFound)
					{
						newArrayStartPosInFile = bytePosForRightFragments(targetFile, startPosInFile[i], targetFile.GetNumberOfBytes() - 1L, 1, 0, bigEndian);
						if (newArrayStartPosInFile.Length == 0)
						{
							subseqFound = false;
						}
						else
						{
							subseqFound = true;
							newValueStartPosInFile = newArrayStartPosInFile[0] + 1L;  //take away +1????
						}
						i++;
					}
				}
			}

			//update the file marker
			if (subseqFound)
			{
				targetFile.SetFileMarker(newValueStartPosInFile);
			}

			return subseqFound;

		}
Ejemplo n.º 5
0
		/**
		 * Searches for this subsequence after the current file marker position in the file.
		 * Moves the file marker to the end of this subsequence.
		 *
		 * @param targetFile   the binary file to be identified
		 * @param reverseOrder  true if file is being searched from right to left
		 * @param bigEndian    True iff our parent signature is big-endian
		 */
		public bool isFoundAfterFileMarker(IByteReader targetFile, bool reverseOrder, bool bigEndian) {
        
        int searchDirection = reverseOrder?-1:1;
        //get the current file marker
        long startPosInFile = targetFile.GetFileMarker();
        //Add the minimum offset before start of sequence and update the file marker accordingly
        startPosInFile = startPosInFile + (long)(searchDirection * this.getMinSeqOffset());
        if (targetFile.GetNumberOfBytes() < startPosInFile)
        {
            // We're looking for a sequence of bytes at an offset which is longer than the file itself
            return false;
        }
        targetFile.SetFileMarker(startPosInFile);
        //start searching for main sequence after the minimum length of the relevant fragments
        startPosInFile = startPosInFile + (long)(searchDirection * this.getMinFragLength());
        long numFileBytes = reverseOrder?(startPosInFile+1):(targetFile.GetNumberOfBytes() - startPosInFile);
        int numSeqBytes = this.getNumBytes();
        bool subSeqFound = false;
        bool endOfFileReached = false;
        while((!subSeqFound) & (!endOfFileReached)) {
            if((long)numSeqBytes> numFileBytes) {
                endOfFileReached = true;
            } else {
                //compare sequence with file contents directly at fileMarker position
                bool missMatchFound = false;
                int byteLoopStart = reverseOrder?numSeqBytes-1:0;
                int byteLoopEnd   = reverseOrder?0:numSeqBytes-1;
                long tempFileMarker = startPosInFile;
                for(int iByte=byteLoopStart; (!missMatchFound) && (iByte<=numSeqBytes-1) && (iByte>=0); iByte+=searchDirection) {
                    missMatchFound = (byteSequence[iByte] != targetFile.GetByte(tempFileMarker));
                    if(!missMatchFound && showProgress) { System.Console.WriteLine("FLOATING SEQ: A match was found for " + this.getByte(iByte).ToString()); }
                    tempFileMarker+=searchDirection;
                }
                if(!missMatchFound) { //subsequence was found at position fileMarker in the file
                    //Now search for fragments between original fileMarker and startPosInFile
                    if(reverseOrder) {
                        long rightFragEnd;
                        long[] rightFragEndArray = bytePosForRightFragments(targetFile, startPosInFile+1, targetFile.GetFileMarker(), 1, 0, bigEndian);
                        if(rightFragEndArray.Length == 0) {
                            missMatchFound = true;
                        } else {
                            rightFragEnd = rightFragEndArray[0];
                            long leftFragEnd;
                            long[] leftFragEndArray = bytePosForLeftFragments(targetFile, 0, startPosInFile - numSeqBytes, -1, 0, bigEndian);
                            if(leftFragEndArray.Length == 0) {
                                missMatchFound = true;
                            } else {
                                leftFragEnd = leftFragEndArray[0];
                                targetFile.SetFileMarker(leftFragEnd-1L);
                                subSeqFound = true;
                            }
                        }
                        
                    } else {  //search is in forward direction
                        long leftFragEnd;
                        long[] leftFragEndArray = bytePosForLeftFragments(targetFile, targetFile.GetFileMarker(), startPosInFile-1L, -1, 0, bigEndian);
                        if(leftFragEndArray.Length == 0) {
                            missMatchFound = true;
                        } else {
                            leftFragEnd = leftFragEndArray[0];
                            long rightFragEnd;
                            long[] rightFragEndArray = bytePosForRightFragments(targetFile, startPosInFile + numSeqBytes, targetFile.GetNumberOfBytes()-1L, 1, 0, bigEndian);
                            if(rightFragEndArray.Length == 0) {
                                missMatchFound = true;
                            } else {
                                rightFragEnd = rightFragEndArray[0];
                                targetFile.SetFileMarker(rightFragEnd+1L);
                                subSeqFound = true;
                            }
                        }
                    }
                    
                }
                if(missMatchFound) {
                    if (startPosInFile+(long)(searchDirection*numSeqBytes)>=targetFile.GetNumberOfBytes()) {
                        endOfFileReached = true;
                    } else {
                        long numShiftBytes = this.getShift(targetFile.GetByte(startPosInFile+(long)(searchDirection*numSeqBytes))); //reverseOrder?-1:1;   // add shift function for the byte at [fileMarker+(searchDirection*numSeqBytes)] in file
                        numFileBytes -= (numShiftBytes>0)?numShiftBytes:-numShiftBytes;
                        startPosInFile += numShiftBytes;
                        
                        if((startPosInFile<0L) || (startPosInFile>=targetFile.GetNumberOfBytes())) {
                            endOfFileReached = true;
                        }
                    }
                }
            }
        }
        return subSeqFound;
    }
Ejemplo n.º 6
0
        /**
         * Searches for this subsequence at the start of the current file.
         * Moves the file marker to the end of this subsequence.
         *
         * @param targetFile   the binary file to be identified
         * @param reverseOrder  true if file is being searched from right to left
         * @param bigEndian    True iff our parent signature is big-endian
         */
        public bool isFoundAtStartOfFile(IByteReader targetFile, bool reverseOrder, bool bigEndian)
        {
            int searchDirection = reverseOrder ? -1 : 1;
            int minSeqOffset    = this.getMinSeqOffset();
            int maxSeqOffset    = this.getMaxSeqOffset();

            long[] startPosInFile = new long[1];
            startPosInFile[0] = reverseOrder ? targetFile.GetNumberOfBytes() - minSeqOffset - 1 : minSeqOffset;
            bool subseqFound = true;
            bool leftFrag    = true;

            if (reverseOrder)
            {
                leftFrag = false;
            }

            //match intial fragment
            if (reverseOrder)
            {
                startPosInFile = bytePosForRightFragments(targetFile, 0, startPosInFile[0], -1, (maxSeqOffset - minSeqOffset), bigEndian);
            }
            else
            {
                startPosInFile = bytePosForLeftFragments(targetFile, startPosInFile[0], targetFile.GetNumberOfBytes() - 1, 1, (maxSeqOffset - minSeqOffset), bigEndian);
            }
            int numOptions = startPosInFile.Length;

            if (numOptions == 0)
            {
                subseqFound = false;
            }
            else
            {
                for (int i = 0; i < numOptions; i++)
                {
                    startPosInFile[i] += (long)searchDirection;
                }
            }

            //match main sequence
            if (subseqFound)
            {
                //move startPosInFile according to min offset of last fragment looked at
                int minOffset = 0;
                int maxOffset = 0;
                if (this.getNumFragmentPositions(leftFrag) > 0)
                {
                    minOffset = this.getFragment(leftFrag, 1, 0).getMinOffset();
                    maxOffset = this.getFragment(leftFrag, 1, 0).getMaxOffset();
                    for (int i = 0; i < numOptions; i++)
                    {
                        startPosInFile[i] += (long)(minOffset * searchDirection);
                    }
                }

                //add new possible values for startPosInFile to allow for difference between maxOffset and minOffset
                int offsetRange = maxOffset - minOffset;
                if (offsetRange > 0)
                {
                    long[] newStartPosInFile = new long[numOptions * (offsetRange + 1)];
                    for (int i = 0; i <= offsetRange; i++)
                    {
                        for (int j = 0; j < numOptions; j++)
                        {
                            newStartPosInFile[j + i * numOptions] = startPosInFile[j] + (long)(i * searchDirection);
                        }
                    }
                    //Arrays.sort(newStartPosInFile);
                    System.Array.Sort(newStartPosInFile);

                    int newNumOptions = 1;
                    for (int i = 1; i < numOptions * (offsetRange + 1); i++)
                    {
                        if (newStartPosInFile[i] > newStartPosInFile[newNumOptions - 1])
                        {
                            newStartPosInFile[newNumOptions] = newStartPosInFile[i];
                            newNumOptions++;
                        }
                    }
                    //now copy these back to the startPosInFile array (sorted in searchDirection)
                    numOptions = newNumOptions;
                    if (searchDirection > 1)
                    {
                        System.Array.Copy(newStartPosInFile, 0, startPosInFile, 0, numOptions);
                    }
                    else
                    {
                        //reverse order copy
                        for (int i = 0; i < numOptions; i++)
                        {
                            startPosInFile[i] = newStartPosInFile[numOptions - 1 - i];
                        }
                    }
                }

                //check that the end of the file is not going to be reached
                int  numSeqBytes    = this.getNumBytes();
                long numBytesInFile = targetFile.GetNumberOfBytes();
                if (reverseOrder)
                {
                    //cutoff if startPosInFile is too close to start of file
                    for (int i = 0; i < numOptions; i++)
                    {
                        if (startPosInFile[i] < ((long)numSeqBytes - 1L))
                        {
                            numOptions = i;
                        }
                    }
                }
                else
                {
                    //cutoff if startPosInFile is too close to end of file
                    for (int i = 0; i < numOptions; i++)
                    {
                        if (startPosInFile[i] > (numBytesInFile - (long)numSeqBytes))
                        {
                            numOptions = i;
                        }
                    }
                }

                /*
                 * long refNumTries = (long)(maxOffset - minOffset) + 1L;  //this is the expected number of attempts to get a match
                 * //correct the number of attempts for each starting position depending on whether the end of the file may be reached
                 * long[] maxNumTries = new long[numOptions];
                 * if(reverseOrder) {
                 *       for(int i=0; i<numOptions; i++) {
                 *               long tempNumTries = (startPosInFile[i]+1L) - (long)numSeqBytes + 1L;
                 *               maxNumTries[i] = tempNumTries<refNumTries ? tempNumTries : refNumTries;
                 *       }
                 * } else {
                 *      for(int i=0; i<numOptions; i++) {
                 *              long tempNumTries = (numBytesInFile - startPosInFile[i]) - numSeqBytes + 1L;
                 *               maxNumTries[i] = tempNumTries<refNumTries ? tempNumTries : refNumTries;
                 *      }
                 * }
                 */

                for (int iOption = 0; iOption < numOptions; iOption++)
                {
                    //compare sequence with file contents directly at fileMarker position
                    int  byteLoopStart  = reverseOrder ? numSeqBytes - 1 : 0;
                    int  byteLoopEnd    = reverseOrder ? 0 : numSeqBytes - 1;
                    long tempFileMarker = startPosInFile[iOption];
                    bool provSeqMatch   = true;

                    //check whether the file and signature sequences match
                    for (int iByte = byteLoopStart; (provSeqMatch) && (iByte <= numSeqBytes - 1) && (iByte >= 0); iByte += searchDirection)
                    {
                        provSeqMatch    = (byteSequence[iByte] == targetFile.GetByte(tempFileMarker));
                        tempFileMarker += searchDirection;
                    }

                    if (!provSeqMatch)
                    {
                        //no match
                        startPosInFile[iOption] = -2L;
                    }
                    else
                    {
                        //success: a match was found - update the startPosInFile
                        startPosInFile[iOption] = tempFileMarker;
                    }
                }


                //check the startPosInFile array: remove -2 values, reorder and remove duplicates
                System.Array.Sort(startPosInFile, 0, numOptions);
                int    newNumOptions2     = 0;
                long[] newStartPosInFile2 = new long[numOptions];
                if (numOptions > 0)
                {
                    if (startPosInFile[0] >= -1L)
                    {
                        newStartPosInFile2[0] = startPosInFile[0];
                        newNumOptions2        = 1;
                    }
                }
                for (int i = 1; i < numOptions; i++)
                {
                    if (startPosInFile[i] > startPosInFile[i - 1])
                    {
                        newStartPosInFile2[newNumOptions2] = startPosInFile[i];
                        newNumOptions2++;
                    }
                }

                if (newNumOptions2 == 0)
                {
                    subseqFound = false;
                }
                else
                {
                    numOptions = newNumOptions2;
                    if (searchDirection < 0)
                    {
                        //for right to left search direction, reorder in reverse
                        for (int iOption = 0; iOption < numOptions; iOption++)
                        {
                            startPosInFile[iOption] = newStartPosInFile2[numOptions - 1 - iOption];
                        }
                    }
                    else
                    {
                        //for left to right search direction, copy over as is
                        System.Array.Copy(newStartPosInFile2, 0, startPosInFile, 0, numOptions);
                    }
                }
            }


            //match remaining sequence fragment
            long newValueStartPosInFile = 0L;

            if (subseqFound)
            {
                long[] newArrayStartPosInFile;
                if (reverseOrder)
                {
                    int i = 0;
                    subseqFound = false;
                    while (i < numOptions && !subseqFound)
                    {
                        newArrayStartPosInFile = bytePosForLeftFragments(targetFile, 0L, startPosInFile[i], -1, 0, bigEndian);
                        if (newArrayStartPosInFile.Length == 0)
                        {
                            subseqFound = false;
                        }
                        else
                        {
                            subseqFound            = true;
                            newValueStartPosInFile = newArrayStartPosInFile[0] - 1L;                              //take away -1???
                        }
                        i++;
                    }
                }
                else
                {
                    int i = 0;
                    subseqFound = false;
                    while (i < numOptions && !subseqFound)
                    {
                        newArrayStartPosInFile = bytePosForRightFragments(targetFile, startPosInFile[i], targetFile.GetNumberOfBytes() - 1L, 1, 0, bigEndian);
                        if (newArrayStartPosInFile.Length == 0)
                        {
                            subseqFound = false;
                        }
                        else
                        {
                            subseqFound            = true;
                            newValueStartPosInFile = newArrayStartPosInFile[0] + 1L;                              //take away +1????
                        }
                        i++;
                    }
                }
            }

            //update the file marker
            if (subseqFound)
            {
                targetFile.SetFileMarker(newValueStartPosInFile);
            }

            return(subseqFound);
        }
Ejemplo n.º 7
0
        /**
         * Searches for this subsequence after the current file marker position in the file.
         * Moves the file marker to the end of this subsequence.
         *
         * @param targetFile   the binary file to be identified
         * @param reverseOrder  true if file is being searched from right to left
         * @param bigEndian    True iff our parent signature is big-endian
         */
        public bool isFoundAfterFileMarker(IByteReader targetFile, bool reverseOrder, bool bigEndian)
        {
            int searchDirection = reverseOrder?-1:1;
            //get the current file marker
            long startPosInFile = targetFile.GetFileMarker();

            //Add the minimum offset before start of sequence and update the file marker accordingly
            startPosInFile = startPosInFile + (long)(searchDirection * this.getMinSeqOffset());
            if (targetFile.GetNumberOfBytes() < startPosInFile)
            {
                // We're looking for a sequence of bytes at an offset which is longer than the file itself
                return(false);
            }
            targetFile.SetFileMarker(startPosInFile);
            //start searching for main sequence after the minimum length of the relevant fragments
            startPosInFile = startPosInFile + (long)(searchDirection * this.getMinFragLength());
            long numFileBytes     = reverseOrder?(startPosInFile + 1):(targetFile.GetNumberOfBytes() - startPosInFile);
            int  numSeqBytes      = this.getNumBytes();
            bool subSeqFound      = false;
            bool endOfFileReached = false;

            while ((!subSeqFound) & (!endOfFileReached))
            {
                if ((long)numSeqBytes > numFileBytes)
                {
                    endOfFileReached = true;
                }
                else
                {
                    //compare sequence with file contents directly at fileMarker position
                    bool missMatchFound = false;
                    int  byteLoopStart  = reverseOrder?numSeqBytes - 1:0;
                    int  byteLoopEnd    = reverseOrder?0:numSeqBytes - 1;
                    long tempFileMarker = startPosInFile;
                    for (int iByte = byteLoopStart; (!missMatchFound) && (iByte <= numSeqBytes - 1) && (iByte >= 0); iByte += searchDirection)
                    {
                        missMatchFound = (byteSequence[iByte] != targetFile.GetByte(tempFileMarker));
                        if (!missMatchFound && showProgress)
                        {
                            System.Console.WriteLine("FLOATING SEQ: A match was found for " + this.getByte(iByte).ToString());
                        }
                        tempFileMarker += searchDirection;
                    }
                    if (!missMatchFound) //subsequence was found at position fileMarker in the file
                    //Now search for fragments between original fileMarker and startPosInFile
                    {
                        if (reverseOrder)
                        {
                            long   rightFragEnd;
                            long[] rightFragEndArray = bytePosForRightFragments(targetFile, startPosInFile + 1, targetFile.GetFileMarker(), 1, 0, bigEndian);
                            if (rightFragEndArray.Length == 0)
                            {
                                missMatchFound = true;
                            }
                            else
                            {
                                rightFragEnd = rightFragEndArray[0];
                                long   leftFragEnd;
                                long[] leftFragEndArray = bytePosForLeftFragments(targetFile, 0, startPosInFile - numSeqBytes, -1, 0, bigEndian);
                                if (leftFragEndArray.Length == 0)
                                {
                                    missMatchFound = true;
                                }
                                else
                                {
                                    leftFragEnd = leftFragEndArray[0];
                                    targetFile.SetFileMarker(leftFragEnd - 1L);
                                    subSeqFound = true;
                                }
                            }
                        }
                        else  //search is in forward direction
                        {
                            long   leftFragEnd;
                            long[] leftFragEndArray = bytePosForLeftFragments(targetFile, targetFile.GetFileMarker(), startPosInFile - 1L, -1, 0, bigEndian);
                            if (leftFragEndArray.Length == 0)
                            {
                                missMatchFound = true;
                            }
                            else
                            {
                                leftFragEnd = leftFragEndArray[0];
                                long   rightFragEnd;
                                long[] rightFragEndArray = bytePosForRightFragments(targetFile, startPosInFile + numSeqBytes, targetFile.GetNumberOfBytes() - 1L, 1, 0, bigEndian);
                                if (rightFragEndArray.Length == 0)
                                {
                                    missMatchFound = true;
                                }
                                else
                                {
                                    rightFragEnd = rightFragEndArray[0];
                                    targetFile.SetFileMarker(rightFragEnd + 1L);
                                    subSeqFound = true;
                                }
                            }
                        }
                    }
                    if (missMatchFound)
                    {
                        if (startPosInFile + (long)(searchDirection * numSeqBytes) >= targetFile.GetNumberOfBytes())
                        {
                            endOfFileReached = true;
                        }
                        else
                        {
                            long numShiftBytes = this.getShift(targetFile.GetByte(startPosInFile + (long)(searchDirection * numSeqBytes))); //reverseOrder?-1:1;   // add shift function for the byte at [fileMarker+(searchDirection*numSeqBytes)] in file
                            numFileBytes   -= (numShiftBytes > 0)?numShiftBytes:-numShiftBytes;
                            startPosInFile += numShiftBytes;

                            if ((startPosInFile < 0L) || (startPosInFile >= targetFile.GetNumberOfBytes()))
                            {
                                endOfFileReached = true;
                            }
                        }
                    }
                }
            }
            return(subSeqFound);
        }
        /**
         * Determines whether or not a given portion of a binary file matches the sequence of bytes we specify.
         *
         * @param file       The file we're currently testing
         * @param startPos   The position of the first byte in the file to examine
         * @param direction  +1 (left to right) or -1 (right to left).  The overall direction which our caller is searching in
         * @param bigEndian  True iff the signature we are matching is big-endian
         * @return true iff the portion matches
         *
         * Note: In an ideal world, we would hold bigEndian as a private member, set up on construction.  However, the framework
         *       used during parsing of the XML file does not lend itself to easily fetching information from a grandparent
         *       element.  Consequently, we parse the byte sequence specifier in ignorance of its endianness, and wait until
         *       we try to match against a specific byte sequence (here) to find out how minSeq and maxSeq should be interpreted.
         */
        public bool matchesByteSequence(IByteReader file, long startPos, int direction, bool bigEndian)
        {
            try {
                // We have to perform the comparison from big-end to little-end.  Consequently, if we're reading
                // from right to left but using big-endian-ness, or if we're reading from left-to-right but using
                // little-endian-ness, we have to search through our sequence backwards -- that is, left-to-right
                // in the former case, or right-to-left in the latter.
                if (!bigEndian && direction == 1)
                {
                    direction = -1;
                    startPos += this.getNumBytes() - 1;
                }
                else if (bigEndian && direction == -1)
                {
                    direction = 1;
                    startPos  = startPos - this.getNumBytes() + 1;
                }
                int arrayPos = (direction == 1) ? 0 : this.getNumBytes() - 1;

                // Loop through the sequence, checking to ensure that the contents of the binary file >= the minimum sequence
                for (int fileOffset = 0; 0 <= arrayPos && arrayPos < this.getNumBytes(); fileOffset += direction, arrayPos += direction)
                {
                    // Read the corresponding byte from the file.  Because this is stored in 2s complement form, we need to
                    // convert it to the same form that minSeq is stored in
                    int fileByte = file.GetByte(startPos + fileOffset);
                    if (fileByte < 0)
                    {
                        fileByte += 256;
                    }
                    fileByte += byte.MinValue;

                    if (fileByte < minSeq[arrayPos])
                    {
                        // We're outside the allowed range.
                        return(negate);
                    }
                    else if (fileByte > minSeq[arrayPos])
                    {
                        // The whole of the sequence is definitely greater than minSeq.  Go on and see if it's less than maxSeq.
                        break;
                    }
                }

                // Repeat the previous loop, but this time checking to ensure that the contents of the binary file <= the maximum sequence
                arrayPos = (direction == 1) ? 0 : this.getNumBytes() - 1;

                for (int fileOffset = 0; arrayPos >= 0 && arrayPos < this.getNumBytes(); fileOffset += direction, arrayPos += direction)
                {
                    int fileByte = file.GetByte(startPos + fileOffset);
                    if (fileByte < 0)
                    {
                        fileByte += 256;
                    }
                    fileByte += byte.MinValue;

                    if (fileByte > maxSeq[arrayPos])
                    {
                        return(negate);
                    }
                    else if (fileByte < maxSeq[arrayPos])
                    {
                        break;
                    }
                }
                return(!negate);
            }
            catch (Exception)
            {
                // This is most likely to occur if we run off the end of the file.  (In practice, this method shouldn't be called
                // unless we have enough bytes to read, but this is belt and braces.)
                return(false);
            }
        }