<commit_before>/*
 * file:       FixDeferFix.java
 * author:     <NAME>
 * copyright:  (c) Tapster Rock Limited 2002-2003
 * date:       31/03/2003
 */

/*
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

package com.tapsterrock.mpp;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.TreeSet;

/**
 * This class represents the a block of variable length data items that appears
 * in the Microsoft Project 98 file format.
 */
final class FixDeferFix extends MPPComponent
{
	/**
	 * Extract the variable size data items from the input stream.
	 * 
	 * @param is Input stream
	 * @throws IOException Thrown on read errors
	 */   
   FixDeferFix (InputStream is)
      throws IOException
   {
      m_data = new byte[is.available()];
      is.read(m_data);
   }

   /**
    * Retrieve a byte array of containing the data starting at the supplied
    * offset in the FixDeferFix file. Note that this method will return null
    * if the requested data is not found for some reason.
    * 
    * @param offset Offset into the file
    * @return Byte array containing the requested data
    */
   public byte[] getByteArray (int offset)
   {
      byte[] result = null;

      if (offset > 0 && offset < m_data.length)
      {
         int nextBlockOffset = MPPUtility.getInt(m_data, offset);
         offset += 4;
            
         int itemSize = MPPUtility.getInt(m_data, offset); 
         offset += 4;         
            
         int blockRemainingSize = 28;
                     
         if (nextBlockOffset != -1 || itemSize <= blockRemainingSize)
         {
            int itemRemainingSize = itemSize;
            result = new byte[itemSize];
            int resultOffset = 0;
                           
            while (nextBlockOffset != -1)
            {
               MPPUtility.getByteArray (m_data, offset, blockRemainingSize, result, resultOffset);
               resultOffset += blockRemainingSize;
               offset += blockRemainingSize;
               itemRemainingSize -= blockRemainingSize;
   
               if (offset != nextBlockOffset)
               {
                  offset = nextBlockOffset;            
               }
                           
               nextBlockOffset = MPPUtility.getInt(m_data, offset);
               offset += 4;
               blockRemainingSize = 32;
            }
   
            MPPUtility.getByteArray (m_data, offset, itemRemainingSize, result, resultOffset);                                                             
         }
      }
            
      return (result);
   }

   /**
    * This method retrieves the string at the specified offset.
    * 
    * @param offset Offset into var data
    * @return String value
    */
   public String getString (int offset)
   {
      String result = null;
      byte[] data = getByteArray (offset);
      if (data != null)
      {
         result = new String (data);
      }

      return (result);
   }

   /**
    * This method retrieves the string at the specified offset.
    * 
    * @param offset Offset into var data
    * @return String value
    */
   public String getUnicodeString (int offset)
   {
      String result = null;
      byte[] data = getByteArray (offset);
      if (data != null)
      {
         result = MPPUtility.getUnicodeString(data);
      }

      return (result);
   }

   /**
    * This method dumps the contents of this FixDeferFix block as a String.
    * Note that this facility is provided as a debugging aid.
    *
    * @return formatted contents of this block
    */
   public String toString ()
   {
      StringWriter sw = new StringWriter ();
      PrintWriter pw = new PrintWriter (sw);
   
      pw.println ("BEGIN FixDeferFix");
         
      //
      // Calculate the block size
      //    
      int available = m_data.length;
         
      //
      // 4 byte header
      //
      int fileOffset = 0;             
      int int1 = MPPUtility.getInt(m_data, fileOffset);
      fileOffset += 4;
               
      //
      // Read data
      //
      int itemSize;
      int itemRemainingSize;
      int blockRemainingSize;
      int skip;
      int nextBlockOffset;
      byte[] buffer;
      int bufferOffset;
      TreeSet skipped = new TreeSet ();
      TreeSet read = new TreeSet ();
      int startOffset;
                                             
      while (fileOffset < available || skipped.size() != 0)
      {     
         Integer temp;
                         
         if (fileOffset >= available)
         {
            temp = (Integer)skipped.first();
            skipped.remove(temp);
            fileOffset = temp.intValue();
         }
         
         temp = new Integer (fileOffset);
         if (read.add(temp) == false)
         {
            fileOffset = available;
            continue;   
         }
         
         startOffset = fileOffset;
               
         nextBlockOffset = MPPUtility.getInt(m_data, fileOffset);
         fileOffset += 4;
            
         itemSize = MPPUtility.getInt(m_data, fileOffset); 
         fileOffset += 4;         
            
         blockRemainingSize = 28;
                     
         if (nextBlockOffset == -1 && itemSize > blockRemainingSize)
         {
            fileOffset += blockRemainingSize;
            continue;
         }
            
         itemRemainingSize = itemSize;
         buffer = new byte[itemSize];
         bufferOffset = 0;
                           
         while (nextBlockOffset != -1)
         {
            MPPUtility.getByteArray (m_data, fileOffset, blockRemainingSize, buffer, bufferOffset);                       
            bufferOffset += blockRemainingSize;
            fileOffset += blockRemainingSize;
            itemRemainingSize -= blockRemainingSize;
   
            if (fileOffset != nextBlockOffset)
            {
               skipped.add(new Integer (fileOffset));
               fileOffset = nextBlockOffset;            
            }
   
            temp = new Integer (fileOffset);
            if (read.add(temp) == false)
            {
               fileOffset = available;
               continue;   
            }
                           
            nextBlockOffset = MPPUtility.getInt(m_data, fileOffset);
            fileOffset += 4;
            blockRemainingSize = 32;
         }
   
         MPPUtility.getByteArray (m_data, fileOffset, itemRemainingSize, buffer, bufferOffset);                                                    
         fileOffset += itemRemainingSize;
            
         if (itemRemainingSize < blockRemainingSize)
         {                    
            skip = blockRemainingSize - itemRemainingSize;
            fileOffset += skip;
         }

         pw.println ("   Data: offset: " + startOffset + " size: " + buffer.length);
         pw.println ("  " + MPPUtility.hexdump (buffer, true));            
      }     
      
      pw.println ("END FixDeferFix");
      pw.println ();
      pw.close();
      
      return (sw.toString());      
   }

   private byte[] m_data;
}
<commit_msg>Updated to fix NPE with zero length calendar names.<commit_after>/*
 * file:       FixDeferFix.java
 * author:     <NAME>
 * copyright:  (c) Tapster Rock Limited 2002-2003
 * date:       31/03/2003
 */

/*
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

package com.tapsterrock.mpp;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.TreeSet;

/**
 * This class represents the a block of variable length data items that appears
 * in the Microsoft Project 98 file format.
 */
final class FixDeferFix extends MPPComponent
{
	/**
	 * Extract the variable size data items from the input stream.
	 * 
	 * @param is Input stream
	 * @throws IOException Thrown on read errors
	 */   
   FixDeferFix (InputStream is)
      throws IOException
   {
      m_data = new byte[is.available()];
      is.read(m_data);
   }

   /**
    * Retrieve a byte array of containing the data starting at the supplied
    * offset in the FixDeferFix file. Note that this method will return null
    * if the requested data is not found for some reason.
    * 
    * @param offset Offset into the file
    * @return Byte array containing the requested data
    */
   public byte[] getByteArray (int offset)
   {
      byte[] result = null;

      if (offset > 0 && offset < m_data.length)
      {
         int nextBlockOffset = MPPUtility.getInt(m_data, offset);
         offset += 4;
            
         int itemSize = MPPUtility.getInt(m_data, offset); 
         offset += 4;         
         
         if (itemSize > 0)
         {   
            int blockRemainingSize = 28;
                        
            if (nextBlockOffset != -1 || itemSize <= blockRemainingSize)
            {
               int itemRemainingSize = itemSize;
               result = new byte[itemSize];
               int resultOffset = 0;
                              
               while (nextBlockOffset != -1)
               {
                  MPPUtility.getByteArray (m_data, offset, blockRemainingSize, result, resultOffset);
                  resultOffset += blockRemainingSize;
                  offset += blockRemainingSize;
                  itemRemainingSize -= blockRemainingSize;
      
                  if (offset != nextBlockOffset)
                  {
                     offset = nextBlockOffset;            
                  }
                              
                  nextBlockOffset = MPPUtility.getInt(m_data, offset);
                  offset += 4;
                  blockRemainingSize = 32;
               }
      
               MPPUtility.getByteArray (m_data, offset, itemRemainingSize, result, resultOffset);                                                             
            }
         }            
      }
            
      return (result);
   }

   /**
    * This method retrieves the string at the specified offset.
    * 
    * @param offset Offset into var data
    * @return String value
    */
   public String getString (int offset)
   {
      String result = null;
      byte[] data = getByteArray (offset);
      if (data != null)
      {
         result = new String (data);
      }

      return (result);
   }

   /**
    * This method retrieves the string at the specified offset.
    * 
    * @param offset Offset into var data
    * @return String value
    */
   public String getUnicodeString (int offset)
   {
      String result = null;
      byte[] data = getByteArray (offset);
      if (data != null)
      {
         result = MPPUtility.getUnicodeString(data);
      }

      return (result);
   }

   /**
    * This method dumps the contents of this FixDeferFix block as a String.
    * Note that this facility is provided as a debugging aid.
    *
    * @return formatted contents of this block
    */
   public String toString ()
   {
      StringWriter sw = new StringWriter ();
      PrintWriter pw = new PrintWriter (sw);
   
      pw.println ("BEGIN FixDeferFix");
         
      //
      // Calculate the block size
      //    
      int available = m_data.length;
         
      //
      // 4 byte header
      //
      int fileOffset = 0;             
      int int1 = MPPUtility.getInt(m_data, fileOffset);
      fileOffset += 4;
               
      //
      // Read data
      //
      int itemSize;
      int itemRemainingSize;
      int blockRemainingSize;
      int skip;
      int nextBlockOffset;
      byte[] buffer;
      int bufferOffset;
      TreeSet skipped = new TreeSet ();
      TreeSet read = new TreeSet ();
      int startOffset;
                                             
      while (fileOffset < available || skipped.size() != 0)
      {     
         Integer temp;
                         
         if (fileOffset >= available)
         {
            temp = (Integer)skipped.first();
            skipped.remove(temp);
            fileOffset = temp.intValue();
         }
         
         temp = new Integer (fileOffset);
         if (read.add(temp) == false)
         {
            fileOffset = available;
            continue;   
         }
         
         startOffset = fileOffset;
               
         nextBlockOffset = MPPUtility.getInt(m_data, fileOffset);
         fileOffset += 4;
            
         itemSize = MPPUtility.getInt(m_data, fileOffset); 
         fileOffset += 4;         
            
         blockRemainingSize = 28;
                     
         if (nextBlockOffset == -1 && itemSize > blockRemainingSize)
         {
            fileOffset += blockRemainingSize;
            continue;
         }
            
         itemRemainingSize = itemSize;
         buffer = new byte[itemSize];
         bufferOffset = 0;
                           
         while (nextBlockOffset != -1)
         {
            MPPUtility.getByteArray (m_data, fileOffset, blockRemainingSize, buffer, bufferOffset);                       
            bufferOffset += blockRemainingSize;
            fileOffset += blockRemainingSize;
            itemRemainingSize -= blockRemainingSize;
   
            if (fileOffset != nextBlockOffset)
            {
               skipped.add(new Integer (fileOffset));
               fileOffset = nextBlockOffset;            
            }
   
            temp = new Integer (fileOffset);
            if (read.add(temp) == false)
            {
               fileOffset = available;
               continue;   
            }
                           
            nextBlockOffset = MPPUtility.getInt(m_data, fileOffset);
            fileOffset += 4;
            blockRemainingSize = 32;
         }
   
         MPPUtility.getByteArray (m_data, fileOffset, itemRemainingSize, buffer, bufferOffset);                                                    
         fileOffset += itemRemainingSize;
            
         if (itemRemainingSize < blockRemainingSize)
         {                    
            skip = blockRemainingSize - itemRemainingSize;
            fileOffset += skip;
         }

         pw.println ("   Data: offset: " + startOffset + " size: " + buffer.length);
         pw.println ("  " + MPPUtility.hexdump (buffer, true));            
      }     
      
      pw.println ("END FixDeferFix");
      pw.println ();
      pw.close();
      
      return (sw.toString());      
   }

   private byte[] m_data;
}

{'fraction_non_alphanumeric': 0.07994955863808323, 'fraction_numerical': 0.007629255989911728, 'mean_word_length': 1.5152235965746907, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5145090', 'n_tokens_mistral': 4176, 'n_tokens_neox': 3988, 'n_words': 1237}