text:
#include "gdal_pam.h"
#include "cpl_string.h"

CPL_CVSID("$Id: bmpdataset.cpp 21680 2011-02-11 21:12:07Z warmerdam $");

CPL_C_START
void    GDALRegister_BMP(void);
CPL_C_END

// Enable if you want to see lots of BMP debugging output.
// #define BMP_DEBUG

enum BMPType
{
    BMPT_WIN4,      // BMP used in Windows 3.0/NT 3.51/95
    BMPT_WIN5,      // BMP used in Windows NT 4.0/98/Me/2000/XP
    BMPT_OS21,      // BMP used in OS/2 PM 1.x
    BMPT_OS22       // BMP used in OS/2 PM 2.x
};

// Bitmap file consists of a BMPFileHeader structure followed by a
// BMPInfoHeader structure. An array of BMPColorEntry structures (also called
// a colour table) follows the bitmap information header structure. The colour
// table is followed by a second array of indexes into the colour table (the
// actual bitmap data). Data may be comressed, for 4-bpp and 8-bpp used RLE
// compression.
//
// +---------------------+
// | BMPFileHeader       |
// +---------------------+
// | BMPInfoHeader       |
// +---------------------+
// | BMPColorEntry array |
// +---------------------+
// | Colour-index array  |
// +---------------------+
//
// All numbers stored in Intel order with least significant byte first.

enum BMPComprMethod
{
    BMPC_RGB = 0L,              // Uncompressed
    BMPC_RLE8 = 1L,             // RLE for 8 bpp images
    BMPC_RLE4 = 2L,             // RLE for 4 bpp images
    BMPC_BITFIELDS = 3L,        // Bitmap is not compressed and the colour table
                                // consists of three DWORD color masks that specify
                                // the red, green, and blue components of each pixel.
                                // This is valid when used with 16- and 32-bpp bitmaps.
    BMPC_JPEG = 4L,             // Indicates that the image is a JPEG image.
    BMPC_PNG = 5L               // Indicates that the image is a PNG image.
};

enum BMPLCSType                 // Type of logical color space.
{
    BMPLT_CALIBRATED_RGB = 0,   // This value indicates that endpoints and gamma
                                // values are given in the appropriate fields.
    BMPLT_DEVICE_RGB = 1,
    BMPLT_DEVICE_CMYK = 2
};

typedef struct
{
    GInt32      iCIEX;
    GInt32      iCIEY;
    GInt32      iCIEZ;
} BMPCIEXYZ;

typedef struct                  // This structure contains the x, y, and z
{                               // coordinates of the three colors that correspond
    BMPCIEXYZ   iCIERed;        // to the red, green, and blue endpoints for
    BMPCIEXYZ   iCIEGreen;      // a specified logical color space.
    BMPCIEXYZ   iCIEBlue;
} BMPCIEXYZTriple;

typedef struct
{
    GByte       bType[2];       // Signature "BM"
    GUInt32     iSize;          // Size in bytes of the bitmap file. Should always
                                // be ignored while reading because of error
                                // in Windows 3.0 SDK's description of this field
    GUInt16     iReserved1;     // Reserved, set as 0
    GUInt16     iReserved2;     // Reserved, set as 0
    GUInt32     iOffBits;       // Offset of the image from file start in bytes
} BMPFileHeader;

// File header size in bytes:
const int       BFH_SIZE = 14;

typedef struct
{
    GUInt32     iSize;          // Size of BMPInfoHeader structure in bytes.
                                // Should be used to determine start of the
                                // colour table
    GInt32      iWidth;         // Image width
    GInt32      iHeight;        // Image height. If positive, image has bottom left
                                // origin, if negative --- top left.
    GUInt16     iPlanes;        // Number of image planes (must be set to 1)
    GUInt16     iBitCount;      // Number of bits per pixel (1, 4, 8, 16, 24 or 32).
                                // If 0 then the number of bits per pixel is
                                // specified or is implied by the JPEG or PNG format.
    BMPComprMethod iCompression; // Compression method
    GUInt32     iSizeImage;     // Size of uncomressed image in bytes. May be 0
                                // for BMPC_RGB bitmaps. If iCompression is BI_JPEG
                                // or BI_PNG, iSizeImage indicates the size
                                // of the JPEG or PNG image buffer.
    GInt32      iXPelsPerMeter; // X resolution, pixels per meter (0 if not used)
    GInt32      iYPelsPerMeter; // Y resolution, pixels per meter (0 if not used)
    GUInt32     iClrUsed;       // Size of colour table. If 0, iBitCount should
                                // be used to calculate this value (1<<iBitCount)
    GUInt32     iClrImportant;  // Number of important colours. If 0, all
                                // colours are required

    // Fields above should be used for bitmaps, compatible with Windows NT 3.51
    // and earlier. Windows 98/Me, Windows 2000/XP introduces additional fields:

    GUInt32     iRedMask;       // Colour mask that specifies the red component
                                // of each pixel, valid only if iCompression
                                // is set to BI_BITFIELDS.
    GUInt32     iGreenMask;     // The same for green component
    GUInt32     iBlueMask;      // The same for blue component
    GUInt32     iAlphaMask;     // Colour mask that specifies the alpha
                                // component of each pixel.
    BMPLCSType  iCSType;        // Colour space of the DIB.
    BMPCIEXYZTriple sEndpoints; // This member is ignored unless the iCSType member
                                // specifies BMPLT_CALIBRATED_RGB.
    GUInt32     iGammaRed;      // Toned response curve for red. This member
                                // is ignored unless color values are calibrated
                                // RGB values and iCSType is set to
                                // BMPLT_CALIBRATED_RGB. Specified in 16^16 format.
    GUInt32     iGammaGreen;    // Toned response curve for green.
    GUInt32     iGammaBlue;     // Toned response curve for blue.
} BMPInfoHeader;

// Info header size in bytes:
const unsigned int  BIH_WIN4SIZE = 40; // for BMPT_WIN4
const unsigned int  BIH_WIN5SIZE = 57; // for BMPT_WIN5
const unsigned int  BIH_OS21SIZE = 12; // for BMPT_OS21
const unsigned int  BIH_OS22SIZE = 64; // for BMPT_OS22

// We will use plain byte array instead of this structure, but declaration
// provided for reference
typedef struct
{
    GByte       bBlue;
    GByte       bGreen;
    GByte       bRed;
    GByte       bReserved;      // Must be 0
} BMPColorEntry;

/*****************************************************************/

int countonbits(GUInt32 dw)
{
    int r = 0;
    for(int x = 0; x < 32; x++)
    {
        if((dw & (1 << x)) != 0)
            r++;
    }
    return r;
}

int findfirstonbit(GUInt32 n)
{
    for(int x = 0; x < 32; x++)
    {
        if((n & (1 << x)) != 0)
            return x;
    }
    return -1;
}

/************************************************************************/
/* ==================================================================== */
/*                              BMPDataset                              */
/* ==================================================================== */
/************************************************************************/

class BMPDataset : public GDALPamDataset
{
    friend class BMPRasterBand;
    friend class BMPComprRasterBand;

    BMPFileHeader       sFileHeader;
    BMPInfoHeader       sInfoHeader;
    int                 nColorTableSize, nColorElems;
    GByte               *pabyColorTable;
    GDALColorTable      *poColorTable;
    double              adfGeoTransform[6];
    int                 bGeoTransformValid;

    char                *pszFilename;
    VSILFILE            *fp;

  protected:
    virtual CPLErr      IRasterIO( GDALRWFlag, int, int, int, int,
                                   void *, int, int, GDALDataType,
                                   int, int *, int, int, int );

  public:
                BMPDataset();
                ~BMPDataset();

    static int           Identify( GDALOpenInfo * );
    static GDALDataset  *Open( GDALOpenInfo * );
    static GDALDataset  *Create( const char * pszFilename,
                                int nXSize, int nYSize, int nBands,
                                GDALDataType eType, char ** papszParmList );

    CPLErr              GetGeoTransform( double * padfTransform );
    virtual CPLErr      SetGeoTransform( double * );
};

/************************************************************************/
/* ==================================================================== */
/*                            BMPRasterBand                             */
/* ==================================================================== */
/************************************************************************/

class BMPRasterBand : public GDALPamRasterBand
{
    friend class BMPDataset;

  protected:

    GUInt32         nScanSize;
    unsigned int    iBytesPerPixel;
    GByte           *pabyScan;

  public:

                BMPRasterBand( BMPDataset *, int );
                ~BMPRasterBand();

    virtual CPLErr          IReadBlock( int, int, void * );
    virtual CPLErr          IWriteBlock( int, int, void * );
    virtual GDALColorInterp GetColorInterpretation();
    virtual GDALColorTable  *GetColorTable();
    CPLErr                  SetColorTable( GDALColorTable * );
};

/************************************************************************/
/*                           BMPRasterBand()                            */
/************************************************************************/

BMPRasterBand::BMPRasterBand( BMPDataset *poDS, int nBand )
{
    this->poDS = poDS;
    this->nBand = nBand;
    eDataType = GDT_Byte;
    iBytesPerPixel = poDS->sInfoHeader.iBitCount / 8;

    // We will read one scanline per time. Scanlines in BMP aligned at 4-byte
    // boundary
    nBlockXSize = poDS->GetRasterXSize();

    if (nBlockXSize < (INT_MAX - 31) / poDS->sInfoHeader.iBitCount)
        nScanSize =
            ((poDS->GetRasterXSize() * poDS->sInfoHeader.iBitCount + 31) & ~31) / 8;
    else
    {
        pabyScan = NULL;
        return;
    }
    nBlockYSize = 1;

#ifdef BMP_DEBUG
    CPLDebug( "BMP",
              "Band %d: set nBlockXSize=%d, nBlockYSize=%d, nScanSize=%d",
              nBand, nBlockXSize, nBlockYSize, nScanSize );
#endif

    pabyScan = (GByte *) VSIMalloc( nScanSize );
}

/************************************************************************/
/*                           ~BMPRasterBand()                           */
/************************************************************************/

BMPRasterBand::~BMPRasterBand()
{
    CPLFree( pabyScan );
}

/************************************************************************/
/*                             IReadBlock()                             */
/************************************************************************/

CPLErr BMPRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )
{
    BMPDataset  *poGDS = (BMPDataset *) poDS;
    GUInt32     iScanOffset;
    int         i;

    if ( poGDS->sInfoHeader.iHeight > 0 )
        iScanOffset = poGDS->sFileHeader.iOffBits +
            ( poGDS->GetRasterYSize() - nBlockYOff - 1 ) * nScanSize;
    else
        iScanOffset = poGDS->sFileHeader.iOffBits + nBlockYOff * nScanSize;

    if ( VSIFSeekL( poGDS->fp, iScanOffset, SEEK_SET ) < 0 )
    {
        // XXX: We will not report error here, because file just may be
    // in update state and data for this block will be available later
        if( poGDS->eAccess == GA_Update )
        {
            memset( pImage, 0, nBlockXSize );
            return CE_None;
        }
        else
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Can't seek to offset %ld in input file to read data.",
                      (long) iScanOffset );
            return CE_Failure;
        }
    }
    if ( VSIFReadL( pabyScan, 1, nScanSize, poGDS->fp ) < nScanSize )
    {
        // XXX
        if( poGDS->eAccess == GA_Update )
        {
            memset( pImage, 0, nBlockXSize );
            return CE_None;
        }
        else
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Can't read from offset %ld in input file.",
                      (long) iScanOffset );
            return CE_Failure;
        }
    }

    if ( poGDS->sInfoHeader.iBitCount == 24 ||
         poGDS->sInfoHeader.iBitCount == 32 )
    {
        GByte *pabyTemp = pabyScan + 3 - nBand;

        for ( i = 0; i < nBlockXSize; i++ )
        {
            // Colour triplets in BMP file organized in reverse order:
            // blue, green, red. When we have 32-bit BMP the forth byte
            // in quadriplet should be discarded as it has no meaning.
            // That is why we always use 3 byte count in the following
            // pabyTemp index.
            ((GByte *) pImage)[i] = *pabyTemp;
            pabyTemp += iBytesPerPixel;
        }
    }
    else if ( poGDS->sInfoHeader.iBitCount == 8 )
    {
        memcpy( pImage, pabyScan, nBlockXSize );
    }
    else if ( poGDS->sInfoHeader.iBitCount == 16 )
    {
        // rcg, oct 7/06: Byteswap if necessary, use int16
        // references to file pixels, expand samples to
        // 8-bit, support BMPC_BITFIELDS channel mask indicators,
        // and generalize band handling.

        GUInt16* pScan16 = (GUInt16*)pabyScan;
#ifdef CPL_MSB
        GDALSwapWords( pScan16, sizeof(GUInt16), nBlockXSize, 0);
#endif

        // todo: make these band members and precompute.
        int mask[3], shift[3], size[3];
        float fTo8bit[3];

        if(poGDS->sInfoHeader.iCompression == BMPC_RGB)
        {
            mask[0] = 0x7c00;
            mask[1] = 0x03e0;
            mask[2] = 0x001f;
        }
        else if(poGDS->sInfoHeader.iCompression == BMPC_BITFIELDS)
        {
            mask[0] = poGDS->sInfoHeader.iRedMask;
            mask[1] = poGDS->sInfoHeader.iGreenMask;
            mask[2] = poGDS->sInfoHeader.iBlueMask;
        }
        else
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Unknown 16-bit compression %d.",
                      poGDS->sInfoHeader.iCompression);
            return CE_Failure;
        }

        for(i = 0; i < 3; i++)
        {
            shift[i] = findfirstonbit(mask[i]);
            size[i]  = countonbits(mask[i]);
            if(size[i] > 14 || size[i] == 0)
            {
                CPLError( CE_Failure, CPLE_FileIO,
                          "Bad 16-bit channel mask %8x.",
                          mask[i]);
                return CE_Failure;
            }
            fTo8bit[i] = 255.0f / ((1 << size[i])-1);
        }

        for ( i = 0; i < nBlockXSize; i++ )
        {
            ((GByte *) pImage)[i] = (GByte)
                (0.5f + fTo8bit[nBand-1] *
                    ((pScan16[i] & mask[nBand-1]) >> shift[nBand-1]));
#if 0
        // original code
            switch ( nBand )
            {
                case 1: // Red
                ((GByte *) pImage)[i] = pabyScan[i + 1] & 0x1F;
                break;

                case 2: // Green
                ((GByte *) pImage)[i] =
                    ((pabyScan[i] & 0x03) << 3) |
                    ((pabyScan[i + 1] & 0xE0) >> 5);
                break;

                case 3: // Blue
                ((GByte *) pImage)[i] = (pabyScan[i] & 0x7c) >> 2;
                break;
                default:
                break;
            }
#endif // 0
        }
    }
    else if ( poGDS->sInfoHeader.iBitCount == 4 )
    {
        GByte *pabyTemp = pabyScan;

        for ( i = 0; i < nBlockXSize; i++ )
        {
            // Most significant part of the byte represents leftmost pixel
            if ( i & 0x01 )
                ((GByte *) pImage)[i] = *pabyTemp++ & 0x0F;
            else
                ((GByte *) pImage)[i] = (*pabyTemp & 0xF0) >> 4;
        }
    }
    else if ( poGDS->sInfoHeader.iBitCount == 1 )
    {
        GByte *pabyTemp = pabyScan;

        for ( i = 0; i < nBlockXSize; i++ )
        {
            switch ( i & 0x7 )
            {
                case 0:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x80) >> 7;
                break;
                case 1:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x40) >> 6;
                break;
                case 2:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x20) >> 5;
                break;
                case 3:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x10) >> 4;
                break;
                case 4:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x08) >> 3;
                break;
                case 5:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x04) >> 2;
                break;
                case 6:
                ((GByte *) pImage)[i] = (*pabyTemp & 0x02) >> 1;
                break;
                case 7:
                ((GByte *) pImage)[i] = *pabyTemp++ & 0x01;
                break;
                default:
                break;
            }
        }
    }

    return CE_None;
}

/************************************************************************/
/*                            IWriteBlock()                             */
/************************************************************************/

CPLErr BMPRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
                                   void * pImage )
{
    BMPDataset  *poGDS = (BMPDataset *)poDS;
    int         iInPixel, iOutPixel;
    GUInt32     iScanOffset;

    CPLAssert( poGDS != NULL
               && nBlockXOff >= 0
               && nBlockYOff >= 0
               && pImage != NULL );

    iScanOffset = poGDS->sFileHeader.iOffBits +
            ( poGDS->GetRasterYSize() - nBlockYOff - 1 ) * nScanSize;
    if ( VSIFSeekL( poGDS->fp, iScanOffset, SEEK_SET ) < 0 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Can't seek to offset %ld in output file to write data.\n%s",
                  (long) iScanOffset, VSIStrerror( errno ) );
        return CE_Failure;
    }

    if( poGDS->nBands != 1 )
    {
        memset( pabyScan, 0, nScanSize );
        VSIFReadL( pabyScan, 1, nScanSize, poGDS->fp );
        VSIFSeekL( poGDS->fp, iScanOffset, SEEK_SET );
    }

    for ( iInPixel = 0, iOutPixel = iBytesPerPixel - nBand;
          iInPixel < nBlockXSize; iInPixel++, iOutPixel += poGDS->nBands )
    {
        pabyScan[iOutPixel] = ((GByte *) pImage)[iInPixel];
    }

    if ( VSIFWriteL( pabyScan, 1, nScanSize, poGDS->fp ) < nScanSize )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Can't write block with X offset %d and Y offset %d.\n%s",
                  nBlockXOff, nBlockYOff,
                  VSIStrerror( errno ) );
        return CE_Failure;
    }

    return CE_None;
}

/************************************************************************/
/*                           GetColorTable()                            */
/************************************************************************/

GDALColorTable *BMPRasterBand::GetColorTable()
{
    BMPDataset   *poGDS = (BMPDataset *) poDS;

    return poGDS->poColorTable;
}

/************************************************************************/
/*                           SetColorTable()                            */
/************************************************************************/

CPLErr BMPRasterBand::SetColorTable( GDALColorTable *poColorTable )
{
    BMPDataset  *poGDS = (BMPDataset *) poDS;

    if ( poColorTable )
    {
        GDALColorEntry  oEntry;
        GUInt32         iULong;
        unsigned int    i;

        poGDS->sInfoHeader.iClrUsed = poColorTable->GetColorEntryCount();
        if ( poGDS->sInfoHeader.iClrUsed < 1 ||
             poGDS->sInfoHeader.iClrUsed > (1U << poGDS->sInfoHeader.iBitCount) )
            return CE_Failure;

        VSIFSeekL( poGDS->fp, BFH_SIZE + 32, SEEK_SET );

        iULong = CPL_LSBWORD32( poGDS->sInfoHeader.iClrUsed );
        VSIFWriteL( &iULong, 4, 1, poGDS->fp );
        poGDS->pabyColorTable = (GByte *) CPLRealloc( poGDS->pabyColorTable,
                        poGDS->nColorElems * poGDS->sInfoHeader.iClrUsed );
        if ( !poGDS->pabyColorTable )
            return CE_Failure;

        for( i = 0; i < poGDS->sInfoHeader.iClrUsed; i++ )
        {
            poColorTable->GetColorEntryAsRGB( i, &oEntry );
            poGDS->pabyColorTable[i * poGDS->nColorElems + 3] = 0;
            poGDS->pabyColorTable[i * poGDS->nColorElems + 2] =
                (GByte) oEntry.c1; // Red
            poGDS->pabyColorTable[i * poGDS->nColorElems + 1] =
                (GByte) oEntry.c2; // Green
            poGDS->pabyColorTable[i * poGDS->nColorElems] =
                (GByte) oEntry.c3;     // Blue
        }

        VSIFSeekL( poGDS->fp, BFH_SIZE + poGDS->sInfoHeader.iSize, SEEK_SET );
        if ( VSIFWriteL( poGDS->pabyColorTable, 1,
                poGDS->nColorElems * poGDS->sInfoHeader.iClrUsed, poGDS->fp ) <
             poGDS->nColorElems * (GUInt32) poGDS->sInfoHeader.iClrUsed )
        {
            return CE_Failure;
        }
    }
    else
        return CE_Failure;

    return CE_None;
}

/************************************************************************/
/*                       GetColorInterpretation()                       */
/************************************************************************/

GDALColorInterp BMPRasterBand::GetColorInterpretation()
{
    BMPDataset      *poGDS = (BMPDataset *) poDS;

    if( poGDS->sInfoHeader.iBitCount == 24 ||
        poGDS->sInfoHeader.iBitCount == 32 ||
        poGDS->sInfoHeader.iBitCount == 16 )
    {
        if( nBand == 1 )
            return GCI_RedBand;
        else if( nBand == 2 )
            return GCI_GreenBand;
        else if( nBand == 3 )
            return GCI_BlueBand;
        else
            return GCI_Undefined;
    }
    else
    {
        return GCI_PaletteIndex;
    }
}

/************************************************************************/
/* ==================================================================== */
/*                       BMPComprRasterBand                             */
/* ==================================================================== */
/************************************************************************/

class BMPComprRasterBand : public BMPRasterBand
{
    friend class BMPDataset;

    GByte           *pabyComprBuf;
    GByte           *pabyUncomprBuf;

  public:

                BMPComprRasterBand( BMPDataset *, int );
                ~BMPComprRasterBand();

    virtual CPLErr          IReadBlock( int, int, void * );
//    virtual CPLErr        IWriteBlock( int, int, void * );
};

/************************************************************************/
/*                           BMPComprRasterBand()                       */
/************************************************************************/

BMPComprRasterBand::BMPComprRasterBand( BMPDataset *poDS, int nBand )
    : BMPRasterBand( poDS, nBand )
{
    unsigned int    i, j, k, iLength = 0;
    GUInt32         iComprSize, iUncomprSize;

    iComprSize = poDS->sFileHeader.iSize - poDS->sFileHeader.iOffBits;
    iUncomprSize = poDS->GetRasterXSize() * poDS->GetRasterYSize();

#ifdef DEBUG
    CPLDebug( "BMP", "RLE compression detected." );
    CPLDebug ( "BMP", "Size of compressed buffer %ld bytes,"
               " size of uncompressed buffer %ld bytes.",
               (long) iComprSize, (long) iUncomprSize );
#endif
    /* TODO: it might be interesting to avoid uncompressing the whole data */
    /* in a single pass, especially if nXSize * nYSize is big */
    /* We could read incrementally one row at a time */
    if (poDS->GetRasterXSize() > INT_MAX / poDS->GetRasterYSize())
    {
        CPLError(CE_Failure, CPLE_NotSupported, "Too big dimensions : %d x %d",
                 poDS->GetRasterXSize(), poDS->GetRasterYSize());
        pabyComprBuf = NULL;
        pabyUncomprBuf = NULL;
        return;
    }
    pabyComprBuf = (GByte *) VSIMalloc( iComprSize );
    pabyUncomprBuf = (GByte *) VSIMalloc( iUncomprSize );
    if (pabyComprBuf == NULL ||
        pabyUncomprBuf == NULL)
    {
        CPLFree(pabyComprBuf);
        pabyComprBuf = NULL;
        CPLFree(pabyUncomprBuf);
        pabyUncomprBuf = NULL;
        return;
    }

    VSIFSeekL( poDS->fp, poDS->sFileHeader.iOffBits, SEEK_SET );
    VSIFReadL( pabyComprBuf, 1, iComprSize, poDS->fp );
    i = 0;
    j = 0;
    if ( poDS->sInfoHeader.iBitCount == 8 )         // RLE8
    {
        while( j < iUncomprSize && i < iComprSize )
        {
            if ( pabyComprBuf[i] )
            {
                iLength = pabyComprBuf[i++];
                while( iLength > 0 && j < iUncomprSize && i < iComprSize )
                {
                    pabyUncomprBuf[j++] = pabyComprBuf[i];
                    iLength--;
                }
                i++;
            }
            else
            {
                i++;
                if ( pabyComprBuf[i] == 0 )         // Next scanline
                {
                    i++;
                }
                else if ( pabyComprBuf[i] == 1 )    // End of image
                {
                    break;
                }
                else if ( pabyComprBuf[i] == 2 )    // Move to...
                {
                    i++;
                    if ( i < iComprSize - 1 )
                    {
                        j += pabyComprBuf[i] +
                             pabyComprBuf[i+1] * poDS->GetRasterXSize();
                        i += 2;
                    }
                    else
                        break;
                }
                else                                // Absolute mode
                {
                    if (i < iComprSize)
                        iLength = pabyComprBuf[i++];
                    for ( k = 0; k < iLength && j < iUncomprSize && i < iComprSize; k++ )
                        pabyUncomprBuf[j++] = pabyComprBuf[i++];
                    if ( i & 0x01 )
                        i++;
                }
            }
        }
    }
    else                                            // RLE4
    {
        while( j < iUncomprSize && i < iComprSize )
        {
            if ( pabyComprBuf[i] )
            {
                iLength = pabyComprBuf[i++];
                while( iLength > 0 && j < iUncomprSize && i < iComprSize )
                {
                    if ( iLength & 0x01 )
                        pabyUncomprBuf[j++] = (pabyComprBuf[i] & 0xF0) >> 4;
                    else
                        pabyUncomprBuf[j++] = pabyComprBuf[i] & 0x0F;
                    iLength--;
                }
                i++;
            }
            else
            {
                i++;
                if ( pabyComprBuf[i] == 0 )         // Next scanline
                {
                    i++;
                }
                else if ( pabyComprBuf[i] == 1 )    // End of image
                {
                    break;
                }
                else if ( pabyComprBuf[i] == 2 )    // Move to...
                {
                    i++;
                    if ( i < iComprSize - 1 )
                    {
                        j += pabyComprBuf[i] +
                             pabyComprBuf[i+1] * poDS->GetRasterXSize();
                        i += 2;
                    }
                    else
                        break;
                }
                else                                // Absolute mode
                {
                    if (i < iComprSize)
                        iLength = pabyComprBuf[i++];
                    for ( k = 0; k < iLength && j < iUncomprSize && i < iComprSize; k++ )
                    {
                        if ( k & 0x01 )
                            pabyUncomprBuf[j++] = pabyComprBuf[i++] & 0x0F;
                        else
                            pabyUncomprBuf[j++] = (pabyComprBuf[i] & 0xF0) >> 4;
                    }
                    if ( i & 0x01 )
                        i++;
                }
            }
        }
    }
    // rcg, release compressed buffer here.
    if ( pabyComprBuf )
        CPLFree( pabyComprBuf );
    pabyComprBuf = NULL;

}

/************************************************************************/
/*                           ~BMPComprRasterBand()                      */
/************************************************************************/

BMPComprRasterBand::~BMPComprRasterBand()
{
    if ( pabyComprBuf )
        CPLFree( pabyComprBuf );
    if ( pabyUncomprBuf )
        CPLFree( pabyUncomprBuf );
}

/************************************************************************/
/*                             IReadBlock()                             */
/************************************************************************/

CPLErr BMPComprRasterBand::
    IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage )
{
    memcpy( pImage, pabyUncomprBuf +
            (poDS->GetRasterYSize() - nBlockYOff - 1) * poDS->GetRasterXSize(),
            nBlockXSize );

    return CE_None;
}

/************************************************************************/
/*                           BMPDataset()                               */
/************************************************************************/

BMPDataset::BMPDataset()
{
    pszFilename = NULL;
    fp = NULL;
    nBands = 0;
    bGeoTransformValid = FALSE;
    adfGeoTransform[0] = 0.0;
    adfGeoTransform[1] = 1.0;
    adfGeoTransform[2] = 0.0;
    adfGeoTransform[3] = 0.0;
    adfGeoTransform[4] = 0.0;
    adfGeoTransform[5] = 1.0;
    pabyColorTable = NULL;
    poColorTable = NULL;
    memset( &sFileHeader, 0, sizeof(sFileHeader) );
    memset( &sInfoHeader, 0, sizeof(sInfoHeader) );
}

/************************************************************************/
/*                            ~BMPDataset()                             */
/************************************************************************/

BMPDataset::~BMPDataset()
{
    FlushCache();

    if ( pabyColorTable )
        CPLFree( pabyColorTable );
    if ( poColorTable != NULL )
        delete poColorTable;
    if( fp != NULL )
        VSIFCloseL( fp );
    CPLFree( pszFilename );
}

/************************************************************************/
/*                          GetGeoTransform()                           */
/************************************************************************/

CPLErr BMPDataset::GetGeoTransform( double * padfTransform )
{
    if( bGeoTransformValid )
    {
        memcpy( padfTransform, adfGeoTransform, sizeof(adfGeoTransform[0])*6 );
        return CE_None;
    }

    if( GDALPamDataset::GetGeoTransform( padfTransform ) == CE_None)
        return CE_None;

    if (sInfoHeader.iXPelsPerMeter > 0 && sInfoHeader.iYPelsPerMeter > 0)
    {
        padfTransform[1] = sInfoHeader.iXPelsPerMeter;
        padfTransform[5] = -sInfoHeader.iYPelsPerMeter;
        padfTransform[0] = -0.5*padfTransform[1];
        padfTransform[3] = -0.5*padfTransform[5];
        return CE_None;
    }

    return CE_Failure;
}

/************************************************************************/
/*                          SetGeoTransform()                           */
/************************************************************************/

CPLErr BMPDataset::SetGeoTransform( double * padfTransform )
{
    CPLErr              eErr = CE_None;

    if ( pszFilename && bGeoTransformValid )
    {
        memcpy( adfGeoTransform, padfTransform, sizeof(double) * 6 );

        if ( GDALWriteWorldFile( pszFilename, "wld", adfGeoTransform )
             == FALSE )
        {
            CPLError( CE_Failure, CPLE_FileIO, "Can't write world file." );
            eErr = CE_Failure;
        }
        return eErr;
    }
    else
        return GDALPamDataset::SetGeoTransform( padfTransform );
}

/************************************************************************/
/*                             IRasterIO()                              */
/*                                                                      */
/*      Multi-band raster io handler.  We will use  block based         */
/*      loading is used for multiband BMPs.  That is because they       */
/*      are effectively pixel interleaved, so processing all bands      */
/*      for a given block together avoid extra seeks.                   */
/************************************************************************/

CPLErr BMPDataset::IRasterIO( GDALRWFlag eRWFlag,
                              int nXOff, int nYOff, int nXSize, int nYSize,
                              void *pData, int nBufXSize, int nBufYSize,
                              GDALDataType eBufType,
                              int nBandCount, int *panBandMap,
                              int nPixelSpace, int nLineSpace, int nBandSpace )

{
    if( nBandCount > 1 )
        return GDALDataset::BlockBasedRasterIO(
            eRWFlag, nXOff, nYOff, nXSize, nYSize,
            pData, nBufXSize, nBufYSize, eBufType,
            nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace );
    else
        return
            GDALDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                    pData, nBufXSize, nBufYSize, eBufType,
                                    nBandCount, panBandMap,
                                    nPixelSpace, nLineSpace, nBandSpace );
}

/************************************************************************/
/*                              Identify()                              */
/************************************************************************/

int BMPDataset::Identify( GDALOpenInfo *poOpenInfo )

{
    if( poOpenInfo->nHeaderBytes < 2
        || poOpenInfo->pabyHeader[0] != 'B'
        || poOpenInfo->pabyHeader[1] != 'M' )
        return FALSE;
    else
        return TRUE;
}

/************************************************************************/
/*                                Open()                                */
/************************************************************************/

GDALDataset *BMPDataset::Open( GDALOpenInfo * poOpenInfo )
{
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create a corresponding GDALDataset.                             */
/* -------------------------------------------------------------------- */
    BMPDataset      *poDS;
    VSIStatBufL     sStat;

    poDS = new BMPDataset();
    poDS->eAccess = poOpenInfo->eAccess;

    if( poOpenInfo->eAccess == GA_ReadOnly )
        poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
    else
        poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );
    if ( !poDS->fp )
    {
        delete poDS;
        return NULL;
    }

    VSIStatL(poOpenInfo->pszFilename, &sStat);

/* -------------------------------------------------------------------- */
/*      Read the BMPFileHeader. We need iOffBits value only             */
/* -------------------------------------------------------------------- */
    VSIFSeekL( poDS->fp, 10, SEEK_SET );
    VSIFReadL( &poDS->sFileHeader.iOffBits, 1, 4, poDS->fp );
#ifdef CPL_MSB
    CPL_SWAP32PTR( &poDS->sFileHeader.iOffBits );
#endif
    poDS->sFileHeader.iSize = (GUInt32) sStat.st_size;

#ifdef BMP_DEBUG
    CPLDebug( "BMP", "File size %d bytes.", poDS->sFileHeader.iSize );
    CPLDebug( "BMP", "Image offset 0x%x bytes from file start.",
              poDS->sFileHeader.iOffBits );
#endif

/* -------------------------------------------------------------------- */
/*      Read the BMPInfoHeader.                                         */
/* -------------------------------------------------------------------- */
    BMPType         eBMPType;

    VSIFSeekL( poDS->fp, BFH_SIZE, SEEK_SET );
    VSIFReadL( &poDS->sInfoHeader.iSize, 1, 4, poDS->fp );
#ifdef CPL_MSB
    CPL_SWAP32PTR( &poDS->sInfoHeader.iSize );
#endif

    if ( poDS->sInfoHeader.iSize == BIH_WIN4SIZE )
        eBMPType = BMPT_WIN4;
    else if ( poDS->sInfoHeader.iSize == BIH_OS21SIZE )
        eBMPType = BMPT_OS21;
    else if ( poDS->sInfoHeader.iSize == BIH_OS22SIZE ||
              poDS->sInfoHeader.iSize == 16 )
        eBMPType = BMPT_OS22;
    else
        eBMPType = BMPT_WIN5;

    if ( eBMPType == BMPT_WIN4 || eBMPType == BMPT_WIN5 || eBMPType == BMPT_OS22 )
    {
        VSIFReadL( &poDS->sInfoHeader.iWidth, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iHeight, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iPlanes, 1, 2, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iBitCount, 1, 2, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iCompression, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iSizeImage, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iXPelsPerMeter, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iYPelsPerMeter, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iClrUsed, 1, 4, poDS->fp );
        VSIFReadL( &poDS->sInfoHeader.iClrImportant, 1, 4, poDS->fp );

        // rcg, read win4/5 fields. If we're reading a
        // legacy header that ends at iClrImportant, it turns
        // out that the three DWORD color table entries used
        // by the channel masks start here anyway.
        if(poDS->sInfoHeader.iCompression == BMPC_BITFIELDS)
        {
            VSIFReadL( &poDS->sInfoHeader.iRedMask, 1, 4, poDS->fp );
            VSIFReadL( &poDS->sInfoHeader.iGreenMask, 1, 4, poDS->fp );
            VSIFReadL( &poDS->sInfoHeader.iBlueMask, 1, 4, poDS->fp );
        }
#ifdef CPL_MSB
        CPL_SWAP32PTR( &poDS->sInfoHeader.iWidth );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iHeight );
        CPL_SWAP16PTR( &poDS->sInfoHeader.iPlanes );
        CPL_SWAP16PTR( &poDS->sInfoHeader.iBitCount );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iCompression );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iSizeImage );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iXPelsPerMeter );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iYPelsPerMeter );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iClrUsed );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iClrImportant );
        // rcg, swap win4/5 fields.
        CPL_SWAP32PTR( &poDS->sInfoHeader.iRedMask );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iGreenMask );
        CPL_SWAP32PTR( &poDS->sInfoHeader.iBlueMask );
#endif
        poDS->nColorElems = 4;
    }

    if ( eBMPType == BMPT_OS22 )
    {
        poDS->nColorElems = 3; // FIXME: different info in different documents regarding this!
    }

    if ( eBMPType == BMPT_OS21 )
    {
        GInt16  iShort;

        VSIFReadL( &iShort, 1, 2, poDS->fp );
        poDS->sInfoHeader.iWidth = CPL_LSBWORD16( iShort );
        VSIFReadL( &iShort, 1, 2, poDS->fp );
        poDS->sInfoHeader.iHeight = CPL_LSBWORD16( iShort );
        VSIFReadL( &iShort, 1, 2, poDS->fp );
        poDS->sInfoHeader.iPlanes = CPL_LSBWORD16( iShort );
        VSIFReadL( &iShort, 1, 2, poDS->fp );
        poDS->sInfoHeader.iBitCount = CPL_LSBWORD16( iShort );
        poDS->sInfoHeader.iCompression = BMPC_RGB;
        poDS->nColorElems = 3;
    }

    if ( poDS->sInfoHeader.iBitCount != 1  &&
         poDS->sInfoHeader.iBitCount != 4  &&
         poDS->sInfoHeader.iBitCount != 8  &&
         poDS->sInfoHeader.iBitCount != 16 &&
         poDS->sInfoHeader.iBitCount != 24 &&
         poDS->sInfoHeader.iBitCount != 32 )
    {
        delete poDS;
        return NULL;
    }

#ifdef BMP_DEBUG
    CPLDebug( "BMP", "Windows Device Independent Bitmap parameters:\n"
              " info header size: %d bytes\n"
              " width: %d\n height: %d\n planes: %d\n bpp: %d\n"
              " compression: %d\n image size: %d bytes\n X resolution: %d\n"
              " Y resolution: %d\n colours used: %d\n colours important: %d",
              poDS->sInfoHeader.iSize,
              poDS->sInfoHeader.iWidth, poDS->sInfoHeader.iHeight,
              poDS->sInfoHeader.iPlanes, poDS->sInfoHeader.iBitCount,
              poDS->sInfoHeader.iCompression, poDS->sInfoHeader.iSizeImage,
              poDS->sInfoHeader.iXPelsPerMeter, poDS->sInfoHeader.iYPelsPerMeter,
              poDS->sInfoHeader.iClrUsed, poDS->sInfoHeader.iClrImportant );
#endif

    poDS->nRasterXSize = poDS->sInfoHeader.iWidth;
    poDS->nRasterYSize = (poDS->sInfoHeader.iHeight > 0)?
        poDS->sInfoHeader.iHeight:-poDS->sInfoHeader.iHeight;

    if  (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0)
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Invalid dimensions : %d x %d",
                  poDS->nRasterXSize, poDS->nRasterYSize);
        delete poDS;
        return NULL;
    }

    switch ( poDS->sInfoHeader.iBitCount )
    {
        case 1:
        case 4:
        case 8:
        {
            int     i;

            poDS->nBands = 1;
            // Allocate memory for colour table and read it
            if ( poDS->sInfoHeader.iClrUsed )
                poDS->nColorTableSize = poDS->sInfoHeader.iClrUsed;
            else
                poDS->nColorTableSize = 1 << poDS->sInfoHeader.iBitCount;
            poDS->pabyColorTable =
                (GByte *)VSIMalloc2( poDS->nColorElems, poDS->nColorTableSize );
            if (poDS->pabyColorTable == NULL)
            {
                CPLError(CE_Failure, CPLE_OutOfMemory, "Color palette will be ignored");
                poDS->nColorTableSize = 0;
                break;
            }

            VSIFSeekL( poDS->fp, BFH_SIZE + poDS->sInfoHeader.iSize, SEEK_SET );
            VSIFReadL( poDS->pabyColorTable, poDS->nColorElems,
                      poDS->nColorTableSize, poDS->fp );

            GDALColorEntry oEntry;
            poDS->poColorTable = new GDALColorTable();
            for( i = 0; i < poDS->nColorTableSize; i++ )
            {
                oEntry.c1 = poDS->pabyColorTable[i * poDS->nColorElems + 2]; // Red
                oEntry.c2 = poDS->pabyColorTable[i * poDS->nColorElems + 1]; // Green
                oEntry.c3 = poDS->pabyColorTable[i * poDS->nColorElems];     // Blue
                oEntry.c4 = 255;

                poDS->poColorTable->SetColorEntry( i, &oEntry );
            }
        }
        break;
        case 16:
        case 24:
        case 32:
        poDS->nBands = 3;
        break;
        default:
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int             iBand;

    if ( poDS->sInfoHeader.iCompression == BMPC_RGB
    ||   poDS->sInfoHeader.iCompression == BMPC_BITFIELDS )
    {
        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
        {
            BMPRasterBand* band = new BMPRasterBand( poDS, iBand );
            poDS->SetBand( iBand, band );
            if (band->pabyScan == NULL)
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "The BMP file is probably corrupted or too large. Image width = %d", poDS->nRasterXSize);
                delete poDS;
                return NULL;
            }
        }
    }
    else if ( poDS->sInfoHeader.iCompression == BMPC_RLE8
              || poDS->sInfoHeader.iCompression == BMPC_RLE4 )
    {
        for( iBand = 1; iBand <= poDS->nBands; iBand++ )
        {
            BMPComprRasterBand* band = new BMPComprRasterBand( poDS, iBand );
            poDS->SetBand( iBand, band);
            if (band->pabyUncomprBuf == NULL)
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                          "The BMP file is probably corrupted or too large. Image width = %d", poDS->nRasterXSize);
                delete poDS;
                return NULL;
            }
        }
    }
    else
    {
        delete poDS;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check for world file.                                           */
/* -------------------------------------------------------------------- */
    poDS->bGeoTransformValid =
        GDALReadWorldFile( poOpenInfo->pszFilename, NULL,
                           poDS->adfGeoTransform );

    if( !poDS->bGeoTransformValid )
        poDS->bGeoTransformValid =
            GDALReadWorldFile( poOpenInfo->pszFilename, ".wld",
                               poDS->adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}

/************************************************************************/
/*                               Create()                               */
/************************************************************************/

GDALDataset *BMPDataset::Create( const char * pszFilename,
                                 int nXSize, int nYSize, int nBands,
                                 GDALDataType eType, char **papszOptions )

{
    if( eType != GDT_Byte )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
              "Attempt to create BMP dataset with an illegal\n"
              "data type (%s), only Byte supported by the format.\n",
              GDALGetDataTypeName(eType) );

        return NULL;
    }

    if( nBands != 1 && nBands != 3 )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "BMP driver doesn't support %d bands. Must be 1 or 3.\n",
                  nBands );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    BMPDataset      *poDS;

    poDS = new BMPDataset();

    poDS->fp = VSIFOpenL( pszFilename, "wb+" );
    if( poDS->fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Unable to create file %s.\n",
                  pszFilename );
        delete poDS;
        return NULL;
    }

    poDS->pszFilename = CPLStrdup(pszFilename);

/* -------------------------------------------------------------------- */
/*      Fill the BMPInfoHeader                                          */
/* -------------------------------------------------------------------- */
    GUInt32         nScanSize;

    poDS->sInfoHeader.iSize = 40;
    poDS->sInfoHeader.iWidth = nXSize;
    poDS->sInfoHeader.iHeight = nYSize;
    poDS->sInfoHeader.iPlanes = 1;
    poDS->sInfoHeader.iBitCount = ( nBands == 3 )?24:8;
    poDS->sInfoHeader.iCompression = BMPC_RGB;

    /* XXX: Avoid integer overflow. We can calculate size in one
     * step using
     *
     *   nScanSize = ((poDS->sInfoHeader.iWidth *
     *            poDS->sInfoHeader.iBitCount + 31) & ~31) / 8
     *
     * formulae, but we should check for overflow conditions
     * during calculation.
     */
    nScanSize =
        (GUInt32)poDS->sInfoHeader.iWidth * poDS->sInfoHeader.iBitCount + 31;
    if ( !poDS->sInfoHeader.iWidth
         || !poDS->sInfoHeader.iBitCount
         || (nScanSize - 31) / poDS->sInfoHeader.iBitCount
                != (GUInt32)poDS->sInfoHeader.iWidth )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Wrong image parameters; "
                  "can't allocate space for scanline buffer" );
        delete poDS;

        return NULL;
    }
    nScanSize = (nScanSize & ~31) / 8;

    poDS->sInfoHeader.iSizeImage = nScanSize * poDS->sInfoHeader.iHeight;
    poDS->sInfoHeader.iXPelsPerMeter = 0;
    poDS->sInfoHeader.iYPelsPerMeter = 0;
    poDS->nColorElems = 4;

/* -------------------------------------------------------------------- */
/*      Do we need colour table?                                        */
/* -------------------------------------------------------------------- */
    unsigned int    i;

    if ( nBands == 1 )
    {
        poDS->sInfoHeader.iClrUsed = 1 << poDS->sInfoHeader.iBitCount;
        poDS->pabyColorTable =
            (GByte *) CPLMalloc( poDS->nColorElems * poDS->sInfoHeader.iClrUsed );
        for ( i = 0; i < poDS->sInfoHeader.iClrUsed; i++ )
        {
            poDS->pabyColorTable[i * poDS->nColorElems] =
                poDS->pabyColorTable[i * poDS->nColorElems + 1] =
                poDS->pabyColorTable[i * poDS->nColorElems + 2] =
                poDS->pabyColorTable[i * poDS->nColorElems + 3] = (GByte) i;
        }
    }
    else
    {
        poDS->sInfoHeader.iClrUsed = 0;
    }
    poDS->sInfoHeader.iClrImportant = 0;

/* -------------------------------------------------------------------- */
/*      Fill the BMPFileHeader                                          */
/* -------------------------------------------------------------------- */
    poDS->sFileHeader.bType[0] = 'B';
    poDS->sFileHeader.bType[1] = 'M';
    poDS->sFileHeader.iSize = BFH_SIZE + poDS->sInfoHeader.iSize +
                    poDS->sInfoHeader.iClrUsed * poDS->nColorElems +
                    poDS->sInfoHeader.iSizeImage;
    poDS->sFileHeader.iReserved1 = 0;
    poDS->sFileHeader.iReserved2 = 0;
    poDS->sFileHeader.iOffBits = BFH_SIZE + poDS->sInfoHeader.iSize +
                    poDS->sInfoHeader.iClrUsed * poDS->nColorElems;

/* -------------------------------------------------------------------- */
/*      Write all structures to the file                                */
/* -------------------------------------------------------------------- */
    if( VSIFWriteL( &poDS->sFileHeader.bType, 1, 2, poDS->fp ) != 2 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "Write of first 2 bytes to BMP file %s failed.\n"
                  "Is file system full?",
                  pszFilename );
        delete poDS;

        return NULL;
    }

    GInt32      iLong;
    GUInt32     iULong;
    GUInt16     iUShort;

    iULong = CPL_LSBWORD32( poDS->sFileHeader.iSize );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );
    iUShort = CPL_LSBWORD16( poDS->sFileHeader.iReserved1 );
    VSIFWriteL( &iUShort, 2, 1, poDS->fp );
    iUShort = CPL_LSBWORD16( poDS->sFileHeader.iReserved2 );
    VSIFWriteL( &iUShort, 2, 1, poDS->fp );
    iULong = CPL_LSBWORD32( poDS->sFileHeader.iOffBits );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );

    iULong = CPL_LSBWORD32( poDS->sInfoHeader.iSize );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );
    iLong = CPL_LSBWORD32( poDS->sInfoHeader.iWidth );
    VSIFWriteL( &iLong, 4, 1, poDS->fp );
    iLong = CPL_LSBWORD32( poDS->sInfoHeader.iHeight );
    VSIFWriteL( &iLong, 4, 1, poDS->fp );
    iUShort = CPL_LSBWORD16( poDS->sInfoHeader.iPlanes );
    VSIFWriteL( &iUShort, 2, 1, poDS->fp );
    iUShort = CPL_LSBWORD16( poDS->sInfoHeader.iBitCount );
    VSIFWriteL( &iUShort, 2, 1, poDS->fp );
    iULong = CPL_LSBWORD32( poDS->sInfoHeader.iCompression );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );
    iULong = CPL_LSBWORD32( poDS->sInfoHeader.iSizeImage );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );
    iLong = CPL_LSBWORD32( poDS->sInfoHeader.iXPelsPerMeter );
    VSIFWriteL( &iLong, 4, 1, poDS->fp );
    iLong = CPL_LSBWORD32( poDS->sInfoHeader.iYPelsPerMeter );
    VSIFWriteL( &iLong, 4, 1, poDS->fp );
    iULong = CPL_LSBWORD32( poDS->sInfoHeader.iClrUsed );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );
    iULong = CPL_LSBWORD32( poDS->sInfoHeader.iClrImportant );
    VSIFWriteL( &iULong, 4, 1, poDS->fp );

    if ( poDS->sInfoHeader.iClrUsed )
    {
        if( VSIFWriteL( poDS->pabyColorTable, 1,
                        poDS->nColorElems * poDS->sInfoHeader.iClrUsed, poDS->fp )
            != poDS->nColorElems * poDS->sInfoHeader.iClrUsed )
        {
            CPLError( CE_Failure, CPLE_FileIO,
                      "Error writing color table.  Is disk full?" );
            delete poDS;

            return NULL;
        }
    }

    poDS->nRasterXSize = nXSize;
    poDS->nRasterYSize = nYSize;
    poDS->eAccess = GA_Update;
    poDS->nBands = nBands;

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int         iBand;

    for( iBand = 1; iBand <= poDS->nBands; iBand++ )
    {
        poDS->SetBand( iBand, new BMPRasterBand( poDS, iBand ) );
    }

/* -------------------------------------------------------------------- */
/*      Do we need a world file?                                        */
/* -------------------------------------------------------------------- */
    if( CSLFetchBoolean( papszOptions, "WORLDFILE", FALSE ) )
        poDS->bGeoTransformValid = TRUE;

    return (GDALDataset *) poDS;
}

/************************************************************************/
/*                        GDALRegister_BMP()                            */
/************************************************************************/

void GDALRegister_BMP()

{
    GDALDriver  *poDriver;

    if( GDALGetDriverByName( "BMP" ) == NULL )
    {
        poDriver = new GDALDriver();

        poDriver->SetDescription( "BMP" );
        poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
                                   "MS Windows Device Independent Bitmap" );
        poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
                                   "frmt_bmp.html" );
        poDriver->SetMetadataItem( GDAL_DMD_EXTENSION, "bmp" );
        poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, "Byte" );
        poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST,
"<CreationOptionList>"
"   <Option name='WORLDFILE' type='boolean' description='Write out world file'/>"
"</CreationOptionList>" );

        poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );

        poDriver->pfnOpen = BMPDataset::Open;
        poDriver->pfnCreate = BMPDataset::Create;
        poDriver->pfnIdentify = BMPDataset::Identify;

        GetGDALDriverManager()->RegisterDriver( poDriver );
    }
}


text:
package org.unitime.timetable.onlinesectioning;

import org.unitime.timetable.gwt.shared.SectioningException;

/**
 * @author Tomas Muller
 */
public interface OnlineSectioningActionFactory {

	public <X extends OnlineSectioningAction> X createAction(Class<X> clazz) throws SectioningException;

}

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace Glavweb\CompositeObjectBundle\Event;

/**
 * Class PreRemoveEvent
 *
 * @package Glavweb\CompositeObjectBundle
 * @author Andrey Nilov <nilov@glavweb.ru>
 */
class PreRemoveEvent extends AbstractEvent
{}


text:
module CoolToJS.DontCompile {
    export enum SyntaxKind {
        EndOfInput = 0,
        OpenParenthesis = 1,
        ClosedParenthesis = 2,
        MultiplicationOperator = 3,
        AdditionOperator = 4,
        Integer = 5,
        E = 6,
        WhiteSpace = 100,
        CarriageReturn = 101,
        NewLine = 102,
        Tab = 103,

        // not used in this grammar - only added here so we can compile
        String = 1000,
        Comment = 1001
    }

    export var StartSyntaxKind: SyntaxKind = SyntaxKind.E;

    export interface TokenDefinition {
        token: SyntaxKind;
        regex?: RegExp;
        matchFunction?: (input: string) => string;
    }

    // order signifies priority (keywords are listed first)
    export var TokenLookup: TokenDefinition[] = [
        {
            token: SyntaxKind.Integer,
            regex: /^([0-9]+)\b/,
        },
        {
            token: SyntaxKind.MultiplicationOperator,
            regex: /^(\*)/
        },
        {
            token: SyntaxKind.AdditionOperator,
            regex: /^(\+)/
        },
        {
            token: SyntaxKind.OpenParenthesis,
            regex: /^(\()/
        },
        {
            token: SyntaxKind.ClosedParenthesis,
            regex: /^(\))/
        },
        {
            token: SyntaxKind.WhiteSpace,
            regex: /^( +)/,
        },
        {
            token: SyntaxKind.CarriageReturn,
            regex: /^(\r)/,
        },
        {
            token: SyntaxKind.NewLine,
            regex: /^(\n)/,
        },
        {
            token: SyntaxKind.Tab,
            regex: /^(\t)/,
        },
    ];

    export function isKeyword(tokenType: SyntaxKind) {
        return false;
    }
}


text:
package io.flutter.plugins.camera;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import android.hardware.camera2.params.MeteringRectangle;
import android.util.Size;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

@RunWith(RobolectricTestRunner.class)
public class CameraRegionsTest {

  CameraRegions cameraRegions;

  @Before
  public void setUp() {
    this.cameraRegions = new CameraRegions(new Size(100, 50));
  }

  @Test(expected = AssertionError.class)
  public void getMeteringRectangleForPoint_should_throw_for_x_upper_bound() {
    cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 1.5, 0);
  }

  @Test(expected = AssertionError.class)
  public void getMeteringRectangleForPoint_should_throw_for_x_lower_bound() {
    cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), -0.5, 0);
  }

  @Test(expected = AssertionError.class)
  public void getMeteringRectangleForPoint_should_throw_for_y_upper_bound() {
    cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 0, 1.5);
  }

  @Test(expected = AssertionError.class)
  public void getMeteringRectangleForPoint_should_throw_for_y_lower_bound() {
    cameraRegions.getMeteringRectangleForPoint(new Size(10, 10), 0, -0.5);
  }

  @Test(expected = IllegalStateException.class)
  public void getMeteringRectangleForPoint_should_throw_for_null_boundaries() {
    cameraRegions.getMeteringRectangleForPoint(null, 0, -0);
  }

  @Test
  public void getMeteringRectangleForPoint_should_return_valid_MeteringRectangle() {
    MeteringRectangle r;
    // Center
    r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.5, 0.5);
    assertEquals(new MeteringRectangle(45, 23, 10, 5, 1), r);

    // Top left
    r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.0, 0.0);
    assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), r);

    // Bottom right
    r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 1.0, 1.0);
    assertEquals(new MeteringRectangle(89, 44, 10, 5, 1), r);

    // Top left
    r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 0.0, 1.0);
    assertEquals(new MeteringRectangle(0, 44, 10, 5, 1), r);

    // Top right
    r = cameraRegions.getMeteringRectangleForPoint(cameraRegions.getMaxBoundaries(), 1.0, 0.0);
    assertEquals(new MeteringRectangle(89, 0, 10, 5, 1), r);
  }

  @Test(expected = AssertionError.class)
  public void constructor_should_throw_for_0_width_boundary() {
    new CameraRegions(new Size(0, 50));
  }

  @Test(expected = AssertionError.class)
  public void constructor_should_throw_for_0_height_boundary() {
    new CameraRegions(new Size(100, 0));
  }

  @Test
  public void constructor_should_initialize() {
    CameraRegions cr = new CameraRegions(new Size(100, 50));
    assertEquals(new Size(100, 50), cr.getMaxBoundaries());
    assertNull(cr.getAEMeteringRectangle());
    assertNull(cr.getAFMeteringRectangle());
  }

  @Test
  public void setAutoExposureMeteringRectangleFromPoint_should_set_aeMeteringRectangle_for_point() {
    CameraRegions cr = new CameraRegions(new Size(100, 50));
    cr.setAutoExposureMeteringRectangleFromPoint(0, 0);
    assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), cr.getAEMeteringRectangle());
  }

  @Test
  public void resetAutoExposureMeteringRectangle_should_reset_aeMeteringRectangle() {
    CameraRegions cr = new CameraRegions(new Size(100, 50));
    cr.setAutoExposureMeteringRectangleFromPoint(0, 0);
    assertNotNull(cr.getAEMeteringRectangle());
    cr.resetAutoExposureMeteringRectangle();
    assertNull(cr.getAEMeteringRectangle());
  }

  @Test
  public void setAutoFocusMeteringRectangleFromPoint_should_set_afMeteringRectangle_for_point() {
    CameraRegions cr = new CameraRegions(new Size(100, 50));
    cr.setAutoFocusMeteringRectangleFromPoint(0, 0);
    assertEquals(new MeteringRectangle(0, 0, 10, 5, 1), cr.getAFMeteringRectangle());
  }

  @Test
  public void resetAutoFocusMeteringRectangle_should_reset_afMeteringRectangle() {
    CameraRegions cr = new CameraRegions(new Size(100, 50));
    cr.setAutoFocusMeteringRectangleFromPoint(0, 0);
    assertNotNull(cr.getAFMeteringRectangle());
    cr.resetAutoFocusMeteringRectangle();
    assertNull(cr.getAFMeteringRectangle());
  }
}


text:
The code

     The Kubernetes initiator

       KubeInit provides Ansible playbooks
       and roles to deploy and configure in a single command multiple Kubernetes distributions
       based in a curated list of prescribed architectures.


text:
require 'dbc'

=begin
  * Name: Action
  * Description:
     Base class for player's action
  * Author: phtrivier
  * Date: 11-09-06
  * Licence: GPL-2
=end

class Action

  include DesignByContract

  ##
  # initialize : creates an action from a test block
  # and an action block
  pre(:initialize, "not nil") {|test, action| test!=nil && action!=nil}
  def initialize(test, action)
    @test = test
    @action = action
  end

  ##
  # if the test block returns true when applied to a game,
  # applies the action block on the game.
  # Return true if the attempt was succesfull ; that is,
  # the test returned true.
  def attempt (game)
    res = false
    if (@test.call(game))
      @action.call(game)
      res = true
    end
    return res
  end

end


text:
FOUNDATION_EXPORT double Pods_OAuth2_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_OAuth2_ExampleVersionString[];


text:
"use strict";
var Anyfetch = require('anyfetch');

module.exports.get = function get(req, res, next) {
  var anyfetchClient = new Anyfetch(req.accessToken.token);
  anyfetchClient.getDocuments({
    fields: 'facets.providers',
    limit: 0 // We don't want to retrieve any documents
  }, function updated(err, anyfetchRes) {
    if(!err) {
      var providers = anyfetchRes.body.facets.providers;
      res.send({
        count: providers ? providers.length : 0
      });
    }
    next(err);
  });
};


text:
package gov.hhs.fha.nhinc.connectmgr.uddi.proxy;

import org.apache.log4j.Logger;

import org.uddi.api_v3.BusinessDetail;
import org.uddi.api_v3.BusinessList;
import org.uddi.api_v3.FindBusiness;
import org.uddi.api_v3.GetBusinessDetail;

import gov.hhs.fha.nhinc.messaging.client.CONNECTClient;
import gov.hhs.fha.nhinc.messaging.service.port.ServicePortDescriptor;
import gov.hhs.fha.nhinc.nhin_uddi_api_v3.UDDIInquiryPortType;

/**
 *
 * @author richard.ettema
 */
public class UDDIFindBusinessProxyHPImpl extends UDDIFindBusinessProxyBase {

    private static final Logger LOG = Logger.getLogger(UDDIFindBusinessProxyHPImpl.class);

    /**
     *
     * @return list of businesses from UDDI
     * @throws UDDIFindBusinessException
     */
    @Override
    public BusinessList findBusinessesFromUDDI() throws UDDIFindBusinessException {
        LOG.debug("Using HP Implementation for UDDI Business Info Service");

        BusinessList oBusinessList = null;

        try {
            loadProperties();

            FindBusiness oSearchParams = new FindBusiness();
            oSearchParams.setMaxRows(100);
            ServicePortDescriptor<UDDIInquiryPortType> portDescriptor = new UDDIFindBusinessProxyServicePortDescriptor();
            CONNECTClient<UDDIInquiryPortType> client = getCONNECTClientUnsecured(portDescriptor, uddiInquiryUrl, null);
            oBusinessList = (BusinessList) client.invokePort(UDDIInquiryPortType.class, "findBusiness", oSearchParams);
        } catch (Exception e) {
            String sErrorMessage = "Failed to call 'find_business' web service on the NHIN UDDI server.  Error: "
                    + e.getMessage();
            LOG.error(sErrorMessage, e);
            throw new UDDIFindBusinessException(sErrorMessage, e);
        }

        return oBusinessList;
    }

    @Override
    public BusinessDetail getBusinessDetail(GetBusinessDetail searchParams) throws UDDIFindBusinessException {

        BusinessDetail businessDetail = null;
        try {
            loadProperties();

            ServicePortDescriptor<UDDIInquiryPortType> portDescriptor = new UDDIFindBusinessProxyServicePortDescriptor();
            CONNECTClient<UDDIInquiryPortType> client = getCONNECTClientUnsecured(portDescriptor, uddiInquiryUrl, null);
            businessDetail = (BusinessDetail) client.invokePort(UDDIInquiryPortType.class, "getBusinessDetail",
                    searchParams);

        } catch (Exception e) {
            String sErrorMessage = "Failed to call 'getBusinessDetail' web service on the NHIN UDDI server.  Error: "
                    + e.getMessage();
            LOG.error(sErrorMessage, e);
            throw new UDDIFindBusinessException(sErrorMessage, e);
        }

        return businessDetail;
    }
}


text:
//======================================================================================
// Copyright 5AM Solutions Inc, Yale University
//
// Distributed under the OSI-approved BSD 3-Clause License.
// See http://ncip.github.com/caarray/LICENSE.txt for details.
//======================================================================================
package gov.nih.nci.caarray.web.action.project;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import gov.nih.nci.caarray.application.GenericDataService;
import gov.nih.nci.caarray.application.GenericDataServiceStub;
import gov.nih.nci.caarray.application.project.ProjectManagementService;
import gov.nih.nci.caarray.application.project.ProjectManagementServiceStub;
import gov.nih.nci.caarray.application.project.ProposalWorkflowException;
import gov.nih.nci.caarray.domain.project.Project;
import gov.nih.nci.caarray.security.PermissionDeniedException;
import gov.nih.nci.caarray.security.SecurityUtils;
import gov.nih.nci.caarray.util.CaArrayUsernameHolder;
import gov.nih.nci.caarray.util.j2ee.ServiceLocatorStub;
import gov.nih.nci.caarray.web.AbstractBaseStrutsTest;
import gov.nih.nci.security.authorization.domainobjects.User;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.fiveamsolutions.nci.commons.data.persistent.PersistentObject;
import com.fiveamsolutions.nci.commons.web.struts2.action.ActionHelper;
import com.opensymphony.xwork2.Action;

/**
 * @author Scott Miller
 */
public class ProjectActionTest extends AbstractBaseStrutsTest {

    private static final String WORKSPACE = "workspace";
    ProjectAction action = new ProjectAction();
    private static final ProjectManagementServiceStub projectManagementServiceStub = new LocalProjectManagementServiceStub();
    private static final GenericDataServiceStub genericDataServiceStub = new LocalGenericDataServiceStub();

    @BeforeClass
    @SuppressWarnings("PMD")
    public static void beforeClass() {
        ServiceLocatorStub stub = ServiceLocatorStub.registerEmptyLocator();
        stub.addLookup(ProjectManagementService.JNDI_NAME, projectManagementServiceStub);
        stub.addLookup(GenericDataService.JNDI_NAME, genericDataServiceStub);
    }

    @Before
    public void before() {
        this.action = new ProjectAction() {
            private static final long serialVersionUID = 1L;

            @Override
            protected User getCsmUser() {
                return null;
            }
        };
        projectManagementServiceStub.reset();
    }

    @SuppressWarnings("deprecation")
    private Project getTestProject(Long id) {
        Project p = new Project() {
            private static final long serialVersionUID = 1L;

            @Override
            public boolean hasReadPermission(User user) {
                return (this.getId() == 1l);
            }

            @Override
            public boolean hasWritePermission(User user) {
                return (this.getId() == 1l);
            }

        };
        p.setId(id);
        return p;
    }

    @Test
    public void testPrepare() throws Exception {
        this.action.setProject(this.getTestProject(1l));
        this.action.prepare();
        assertNotNull(this.action.getExperiment());
    }

    @Test
    public void testCreate() throws Exception {
        assertFalse(this.action.isEditMode());
        assertEquals(Action.INPUT, this.action.create());
        assertTrue(this.action.isEditMode());
    }

    @Test
    public void testEdit() {
        this.action.setProject(this.getTestProject(null));
        assertEquals(WORKSPACE, this.action.edit());
        this.action.setProject(this.getTestProject((2l)));
        assertEquals("login-details-id", this.action.edit());
        this.action.setProject(this.getTestProject((1l)));
        assertEquals(Action.INPUT, this.action.edit());
        assertTrue(this.action.isEditMode());
    }

    @Test
    public void testDetails() {
        this.action.setProject(this.getTestProject(null));
        assertEquals(WORKSPACE, this.action.details());
        this.action.setProject(this.getTestProject((2l)));
        assertEquals("login-details-id", this.action.details());
        this.action.setProject(this.getTestProject((1l)));
        assertEquals(Action.INPUT, this.action.details());
        assertFalse(this.action.isEditMode());
    }

    @Test
    public void testChangeStatus() {
        this.action.setWorkflowStatus(Boolean.FALSE);
        this.action.setProject(this.getTestProject(1l));
        assertEquals(WORKSPACE, this.action.changeWorkflowStatus());
        assertEquals(1, projectManagementServiceStub.getChangeWorkflowStatusCount());
        this.action.setProject(this.getTestProject(999l));
        assertEquals(Action.INPUT, this.action.changeWorkflowStatus());
        assertEquals(2, projectManagementServiceStub.getChangeWorkflowStatusCount());
    }

    @Test
    public void testDelete() {
        this.action.setProject(this.getTestProject(1l));
        assertEquals(WORKSPACE, this.action.delete());
        assertTrue(ActionHelper.getMessages().get(0).contains("project.deleted"));
    }

    @Test
    public void testDeleteNonDraft() {
        this.action.setProject(this.getTestProject(1l));
        this.action.getProject().setLocked(true);
        assertEquals(WORKSPACE, this.action.delete());
        assertTrue(ActionHelper.getMessages().get(0).contains("project.deleteOnlyDrafts"));
    }

    @Test
    public void testDeleteNotFound() {
        this.action.setProject(new Project());
        CaArrayUsernameHolder.setUser("someuser");
        assertEquals(WORKSPACE, this.action.delete());
        assertTrue(ActionHelper.getMessages().get(0).contains("project.notFound"));
    }

    @Test(expected = PermissionDeniedException.class)
    public void testDeleteNoWritePermission() {
        this.action.setProject(this.getTestProject(2l));
        CaArrayUsernameHolder.setUser("unauthorizeduser");
        this.action.delete();
    }

    private static class LocalProjectManagementServiceStub extends ProjectManagementServiceStub {
        /**
         * {@inheritDoc}
         */
        public void deleteProject(Project project) throws ProposalWorkflowException {
            if (CaArrayUsernameHolder.getUser().equals("unauthorizeduser")) {
                throw new PermissionDeniedException(project, SecurityUtils.WRITE_PRIVILEGE, CaArrayUsernameHolder.getUser());
            }
            if (project.isLocked()) {
                throw new ProposalWorkflowException("Cannot delete unlocked project");
            }
            // assume success if the checks pass
        }
    }

    private static class LocalGenericDataServiceStub extends GenericDataServiceStub {
        @Override
        public <T extends PersistentObject> T getPersistentObject(Class<T> entityClass, Long entityId) {
            if (Project.class.equals(entityClass)) {
                Project project = new Project();
                project.setId(entityId);
                return (T) project;
            } else {
                return super.getPersistentObject(entityClass, entityId);
            }
        }
    }
}


text:
var isObject = function (obj) {
  return typeof obj === 'object' && obj !== null && !Array.isArray(obj);
};

var isSame = function (a, b) {
  var keys = Object.keys(a);
  for (var x = 0; x < keys.length; x++) {
    if (!b[keys[x]] || a[keys[x]] !== b[keys[x]]) {
      return false;
    }
  }
  return true;
};

module.exports = {
  update: function () {
    this.setState({});
  },
  shouldComponentUpdate: function (nextProps, nextState) {

    var currentPropsLength = this.props ? Object.keys(this.props).length : 0;
    var nextPropsLength = nextProps ? Object.keys(nextProps).length : 0;
    var currentStateLength = this.state ? Object.keys(this.state).length : 0;
    var nextStateLength = nextState ? Object.keys(nextState).length : 0;

    if (!currentPropsLength && !nextPropsLength && !currentStateLength && !nextStateLength) {
      return false;
    } else if (currentPropsLength !== nextPropsLength || currentStateLength !== nextStateLength) {
      return true;
    } else {
      return !isSame(nextProps, this.props) || !isSame(nextState, this.state);
    }

  }
};


text:
package net.bis5.mattermost.model;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.IOException;
import java.util.Arrays;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.bis5.mattermost.model.ContentType.ContentTypeDeserializer;
import net.bis5.mattermost.model.serialize.HasCodeSerializer;

/**
 * The type of content-type.
 *
 * @author Takayuki Maruyama
 */
@Getter
@RequiredArgsConstructor
@JsonSerialize(using = HasCodeSerializer.class)
@JsonDeserialize(using = ContentTypeDeserializer.class)
public enum ContentType implements HasCode<ContentType> {

  FORM("application/x-www-form-urlencoded"), JSON("application/json");
  private final String code;

  public static ContentType of(String code) {
    return Arrays.stream(values()).filter(c -> c.getCode().equals(code)).findFirst().orElse(null);
  }

  static class ContentTypeDeserializer extends JsonDeserializer<ContentType> {

    @Override
    public ContentType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
      String jsonValue = p.getValueAsString();
      return of(jsonValue);
    }
  }

}


text:
import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import Tooltip from 'shared/mixins/tooltip';
import StrippedName from 'shared/mixins/stripped-name';
import layout from './template';
import { observer } from '@ember/object';

export default Component.extend(Tooltip, StrippedName, {
  resourceActions:  service('resource-actions'),
  layout,
  needs:            ['application'],
  inTooltip:        false,
  layoutName:       'tooltip-action-menu',

  model:            alias('tooltipService.tooltipOpts.model'),
  actionsOpen:      alias('resourceActions.open'),
  init() {
    if (this.get('tooltipTemplate')) {
      this.set('layoutName', this.get('tooltipTemplate'));
    }
    this._super(...arguments);
    // Just so openChanged is ready to go, otherwise you have to chain on('init') on openChanged
    // which because of the context menu click on container dot can cause some issues with checking
    // flags and such. This was the least compliated way to ensure that openChanged would recognize changes
    this.set('actionsOpen', false);
  },

  openChanged: observer('actionsOpen', function() {
    this.set('tooltipService.requireClick', this.get('actionsOpen'));
    if ( !this.get('actionsOpen') && !this.get('inTooltip') ) {
      this.get('tooltipService').leave();
    }
  }),

  mouseEnter() {
    this._super();
    this.set('inTooltip', true);

    // Must get the property before it will be observed for openChanged
    // https://github.com/emberjs/ember.js/issues/10821
    this.get('actionsOpen');
  },

  mouseLeave() {
    this.set('inTooltip', false);
    if ( !this.get('actionsOpen') ) {
      this.get('tooltipService').leave();
    }
  },

});


text:
package alluxio.master.block;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import alluxio.Constants;
import alluxio.clock.ManualClock;
import alluxio.conf.Configuration;
import alluxio.conf.PropertyKey;
import alluxio.grpc.Command;
import alluxio.grpc.CommandType;
import alluxio.grpc.RegisterWorkerPOptions;
import alluxio.grpc.StorageList;
import alluxio.grpc.WorkerLostStorageInfo;
import alluxio.heartbeat.HeartbeatContext;
import alluxio.heartbeat.HeartbeatScheduler;
import alluxio.heartbeat.ManuallyScheduleHeartbeat;
import alluxio.master.CoreMasterContext;
import alluxio.master.MasterRegistry;
import alluxio.master.MasterTestUtils;
import alluxio.master.journal.JournalSystem;
import alluxio.master.journal.noop.NoopJournalSystem;
import alluxio.master.metrics.MetricsMaster;
import alluxio.master.metrics.MetricsMasterFactory;
import alluxio.metrics.Metric;
import alluxio.proto.meta.Block;
import alluxio.util.ThreadFactoryUtils;
import alluxio.util.executor.ExecutorServiceFactories;
import alluxio.wire.BlockInfo;
import alluxio.wire.BlockLocation;
import alluxio.wire.WorkerInfo;
import alluxio.wire.WorkerNetAddress;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * Unit tests for {@link BlockMaster}.
 */
public class BlockMasterTest {
  private static final WorkerNetAddress NET_ADDRESS_1 = new WorkerNetAddress().setHost("localhost")
      .setRpcPort(80).setDataPort(81).setWebPort(82);
  private static final WorkerNetAddress NET_ADDRESS_2 = new WorkerNetAddress().setHost("localhost")
      .setRpcPort(83).setDataPort(84).setWebPort(85);

  private static final List<Long> NO_BLOCKS = ImmutableList.of();
  private static final Map<Block.BlockLocation, List<Long>> NO_BLOCKS_ON_LOCATION
      = ImmutableMap.of();
  private static final Map<String, StorageList> NO_LOST_STORAGE = ImmutableMap.of();

  private BlockMaster mBlockMaster;
  private MasterRegistry mRegistry;
  private ManualClock mClock;
  private ExecutorService mExecutorService;
  private ExecutorService mClientExecutorService;
  private MetricsMaster mMetricsMaster;
  private List<Metric> mMetrics;

  /** Rule to create a new temporary folder during each test. */
  @Rule
  public TemporaryFolder mTestFolder = new TemporaryFolder();

  /** The exception expected to be thrown. */
  @Rule
  public ExpectedException mThrown = ExpectedException.none();

  @ClassRule
  public static ManuallyScheduleHeartbeat sManuallySchedule = new ManuallyScheduleHeartbeat(
      HeartbeatContext.MASTER_LOST_WORKER_DETECTION);

  /**
   * Sets up the dependencies before a test runs.
   */
  @Before
  public void before() throws Exception {
    mRegistry = new MasterRegistry();
    mMetrics = Lists.newArrayList();
    JournalSystem journalSystem = new NoopJournalSystem();
    CoreMasterContext masterContext = MasterTestUtils.testMasterContext();
    mMetricsMaster = new MetricsMasterFactory().create(mRegistry, masterContext);
    mClock = new ManualClock();
    mExecutorService =
        Executors.newFixedThreadPool(2, ThreadFactoryUtils.build("TestBlockMaster-%d", true));
    mBlockMaster = new DefaultBlockMaster(mMetricsMaster, masterContext, mClock,
        ExecutorServiceFactories.constantExecutorServiceFactory(mExecutorService));
    mRegistry.add(BlockMaster.class, mBlockMaster);
    mRegistry.start(true);
  }

  /**
   * Stops the master after a test ran.
   */
  @After
  public void after() throws Exception {
    mRegistry.stop();
  }

  @Test
  public void countBytes() throws Exception {
    // Register two workers
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    long worker2 = mBlockMaster.getWorkerId(NET_ADDRESS_2);
    List<String> tiers = Arrays.asList(Constants.MEDIUM_MEM, Constants.MEDIUM_SSD);
    Map<String, Long> worker1TotalBytesOnTiers =
        ImmutableMap.of(Constants.MEDIUM_MEM, 10L, Constants.MEDIUM_SSD, 20L);
    Map<String, Long> worker2TotalBytesOnTiers =
        ImmutableMap.of(Constants.MEDIUM_MEM, 1000L, Constants.MEDIUM_SSD, 2000L);
    Map<String, Long> worker1UsedBytesOnTiers =
        ImmutableMap.of(Constants.MEDIUM_MEM, 1L, Constants.MEDIUM_SSD, 2L);
    Map<String, Long> worker2UsedBytesOnTiers =
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L, Constants.MEDIUM_SSD, 200L);
    mBlockMaster.workerRegister(worker1, tiers, worker1TotalBytesOnTiers, worker1UsedBytesOnTiers,
        NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, RegisterWorkerPOptions.getDefaultInstance());
    mBlockMaster.workerRegister(worker2, tiers, worker2TotalBytesOnTiers, worker2UsedBytesOnTiers,
        NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, RegisterWorkerPOptions.getDefaultInstance());

    // Check that byte counts are summed correctly.
    assertEquals(3030, mBlockMaster.getCapacityBytes());
    assertEquals(303L, mBlockMaster.getUsedBytes());
    assertEquals(ImmutableMap.of(Constants.MEDIUM_MEM, 1010L, Constants.MEDIUM_SSD, 2020L),
        mBlockMaster.getTotalBytesOnTiers());
    assertEquals(ImmutableMap.of(Constants.MEDIUM_MEM, 101L, Constants.MEDIUM_SSD, 202L),
        mBlockMaster.getUsedBytesOnTiers());
  }

  @Test
  public void detectLostWorkers() throws Exception {
    // Register a worker.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker1,
        ImmutableList.of(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 10L),
        NO_BLOCKS_ON_LOCATION,
        NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Advance the block master's clock by an hour so that worker appears lost.
    mClock.setTimeMs(System.currentTimeMillis() + Constants.HOUR_MS);

    // Run the lost worker detector.
    HeartbeatScheduler.execute(HeartbeatContext.MASTER_LOST_WORKER_DETECTION);

    // Make sure the worker is detected as lost.
    List<WorkerInfo> info = mBlockMaster.getLostWorkersInfoList();
    assertEquals(worker1, Iterables.getOnlyElement(info).getId());
  }

  @Test
  public void workerReregisterRemembersLostWorker() throws Exception {
    // Register a worker.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker1,
        ImmutableList.of(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 10L),
        NO_BLOCKS_ON_LOCATION,
        NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Advance the block master's clock by an hour so that the worker appears lost.
    mClock.setTimeMs(System.currentTimeMillis() + Constants.HOUR_MS);

    // Run the lost worker detector.
    HeartbeatScheduler.execute(HeartbeatContext.MASTER_LOST_WORKER_DETECTION);

    // Reregister the worker using its original worker id.
    mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker1,
        ImmutableList.of(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 10L),
        NO_BLOCKS_ON_LOCATION,
        NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Check that there are no longer any lost workers and there is a live worker.
    assertEquals(1, mBlockMaster.getWorkerCount());
    assertEquals(0, mBlockMaster.getLostWorkersInfoList().size());
  }

  @Test
  public void removeBlockTellsWorkersToRemoveTheBlock() throws Exception {
    // Create a worker with a block.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    long blockId = 1L;
    mBlockMaster.workerRegister(worker1, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());
    mBlockMaster.commitBlock(worker1, 50L,
        Constants.MEDIUM_MEM, Constants.MEDIUM_MEM, blockId, 20L);

    // Remove the block
    mBlockMaster.removeBlocks(Arrays.asList(1L), /*delete=*/false);

    // Check that the worker heartbeat tells the worker to remove the block.
    Map<String, Long> memUsage = ImmutableMap.of(Constants.MEDIUM_MEM, 0L);
    alluxio.grpc.Command heartBeat = mBlockMaster.workerHeartbeat(worker1, null, memUsage,
        NO_BLOCKS, NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, mMetrics);
    assertEquals(ImmutableList.of(1L), heartBeat.getDataList());
  }

  @Test
  public void registerCleansUpOrphanedBlocks() throws Exception {
    // Create a worker with unknown blocks.
    long workerId = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    List<Long> orphanedBlocks = Arrays.asList(1L, 2L);
    Map<String, Long> memUsage = ImmutableMap.of(Constants.MEDIUM_MEM, 10L);

    Block.BlockLocation blockLoc = Block.BlockLocation.newBuilder()
        .setWorkerId(workerId).setTier(Constants.MEDIUM_MEM)
        .setMediumType(Constants.MEDIUM_MEM).build();
    mBlockMaster.workerRegister(workerId, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        memUsage, ImmutableMap.of(blockLoc, orphanedBlocks), NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Check that the worker heartbeat tells the worker to remove the blocks.
    alluxio.grpc.Command heartBeat = mBlockMaster.workerHeartbeat(workerId, null,
        memUsage, NO_BLOCKS, NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, mMetrics);
    assertEquals(orphanedBlocks,
        heartBeat.getDataList().stream().sorted().collect(Collectors.toList()));
  }

  @Test
  public void workerHeartbeatUpdatesMemoryCount() throws Exception {
    // Create a worker.
    long worker = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    Map<String, Long> initialUsedBytesOnTiers = ImmutableMap.of(Constants.MEDIUM_MEM, 50L);
    mBlockMaster.workerRegister(worker, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        initialUsedBytesOnTiers, NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Update used bytes with a worker heartbeat.
    Map<String, Long> newUsedBytesOnTiers = ImmutableMap.of(Constants.MEDIUM_MEM, 50L);
    mBlockMaster.workerHeartbeat(worker, null, newUsedBytesOnTiers,
        NO_BLOCKS, NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, mMetrics);

    WorkerInfo workerInfo = Iterables.getOnlyElement(mBlockMaster.getWorkerInfoList());
    assertEquals(50, workerInfo.getUsedBytes());
  }

  @Test
  public void workerHeartbeatUpdatesRemovedBlocks() throws Exception {
    // Create a worker.
    long worker = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());
    long blockId = 1L;
    mBlockMaster.commitBlock(worker, 50L, Constants.MEDIUM_MEM,
        Constants.MEDIUM_MEM, blockId, 20L);

    // Indicate that blockId is removed on the worker.
    mBlockMaster.workerHeartbeat(worker, null,
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L),
        ImmutableList.of(blockId), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE, mMetrics);
    assertTrue(mBlockMaster.getBlockInfo(blockId).getLocations().isEmpty());
  }

  @Test
  public void workerHeartbeatUpdatesAddedBlocks() throws Exception {
    // Create two workers.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker1, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());
    long worker2 = mBlockMaster.getWorkerId(NET_ADDRESS_2);
    mBlockMaster.workerRegister(worker2, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    // Commit blockId to worker1.
    long blockId = 1L;
    mBlockMaster.commitBlock(worker1, 50L, Constants.MEDIUM_MEM,
        Constants.MEDIUM_MEM, blockId, 20L);

    // Send a heartbeat from worker2 saying that it's added blockId.
    List<Long> addedBlocks = ImmutableList.of(blockId);
    Block.BlockLocation blockOnWorker2 = Block.BlockLocation.newBuilder()
        .setWorkerId(worker2).setTier(Constants.MEDIUM_MEM)
        .setMediumType(Constants.MEDIUM_MEM).build();
    mBlockMaster.workerHeartbeat(worker2, null,
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS,
        ImmutableMap.of(blockOnWorker2, addedBlocks),
        NO_LOST_STORAGE, mMetrics);

    // The block now has two locations.
    assertEquals(2, mBlockMaster.getBlockInfo(blockId).getLocations().size());
  }

  @Test
  public void workerHeartbeatUpdatesLostStorage() throws Exception {
    // Create two workers.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    mBlockMaster.workerRegister(worker1, Arrays.asList(Constants.MEDIUM_MEM, Constants.MEDIUM_SSD),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L, Constants.MEDIUM_SSD, 200L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L, Constants.MEDIUM_SSD, 0L),
        NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());
    long worker2 = mBlockMaster.getWorkerId(NET_ADDRESS_2);
    mBlockMaster.workerRegister(worker2, Arrays.asList(Constants.MEDIUM_MEM, Constants.MEDIUM_HDD),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L, Constants.MEDIUM_HDD, 300L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L, Constants.MEDIUM_HDD, 0L),
        NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());

    Map<String, StorageList> lostStorageOnWorker1 = new HashMap<>();
    lostStorageOnWorker1.put(Constants.MEDIUM_SSD, StorageList.newBuilder()
        .addAllStorage(Arrays.asList("/ssd/one", "/ssd/two")).build());
    Map<String, StorageList> lostStorageOnWorker2 = new HashMap<>();
    lostStorageOnWorker2.put(Constants.MEDIUM_HDD,
        StorageList.newBuilder().addStorage("/hdd/one").build());

    mBlockMaster.workerHeartbeat(worker1,
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L, Constants.MEDIUM_SSD, 0L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L, Constants.MEDIUM_SSD, 0L), NO_BLOCKS,
        NO_BLOCKS_ON_LOCATION, lostStorageOnWorker1, mMetrics);
    mBlockMaster.workerHeartbeat(worker2,
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L, Constants.MEDIUM_HDD, 200L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L, Constants.MEDIUM_HDD, 0L), NO_BLOCKS,
        NO_BLOCKS_ON_LOCATION, lostStorageOnWorker2, mMetrics);

    // Two workers have lost storage paths
    assertEquals(2, mBlockMaster.getWorkerLostStorage().size());
    int lostStorageNum = 0;
    for (WorkerLostStorageInfo info : mBlockMaster.getWorkerLostStorage()) {
      for (StorageList list : info.getLostStorageMap().values()) {
        lostStorageNum += list.getStorageList().size();
      }
    }
    assertEquals(3, lostStorageNum);
  }

  @Test
  public void unknownWorkerHeartbeatTriggersRegisterRequest() {
    Command heartBeat = mBlockMaster.workerHeartbeat(0, null, null, null, null, null, mMetrics);
    assertEquals(Command.newBuilder().setCommandType(CommandType.Register).build(), heartBeat);
  }

  @Test
  public void stopTerminatesExecutorService() throws Exception {
    mBlockMaster.stop();
    assertTrue(mExecutorService.isTerminated());
  }

  @Test
  public void getBlockInfo() throws Exception {
    // Create a worker with a block.
    long worker1 = mBlockMaster.getWorkerId(NET_ADDRESS_1);
    long blockId = 1L;
    long blockLength = 20L;
    mBlockMaster.workerRegister(worker1, Arrays.asList(Constants.MEDIUM_MEM),
        ImmutableMap.of(Constants.MEDIUM_MEM, 100L),
        ImmutableMap.of(Constants.MEDIUM_MEM, 0L), NO_BLOCKS_ON_LOCATION, NO_LOST_STORAGE,
        RegisterWorkerPOptions.getDefaultInstance());
    mBlockMaster.commitBlock(worker1, 50L, Constants.MEDIUM_MEM,
        Constants.MEDIUM_MEM, blockId, blockLength);

    BlockLocation blockLocation = new BlockLocation()
        .setTierAlias(Constants.MEDIUM_MEM)
        .setWorkerAddress(NET_ADDRESS_1)
        .setWorkerId(worker1)
        .setMediumType(Constants.MEDIUM_MEM);
    BlockInfo expectedBlockInfo = new BlockInfo()
        .setBlockId(1L)
        .setLength(20L)
        .setLocations(ImmutableList.of(blockLocation));
    assertEquals(expectedBlockInfo, mBlockMaster.getBlockInfo(blockId));
  }

  @Test
  public void getNewContainerId() throws Exception {
    final int total = 10_000;
    long containerIdReservationSize = Configuration.getInt(
        PropertyKey.MASTER_CONTAINER_ID_RESERVATION_SIZE);

    final int parallelNum = 5;
    ExecutorService containerIdFetcher = Executors.newFixedThreadPool(parallelNum);
    AtomicInteger times = new AtomicInteger(0);
    assertEquals(0L, mBlockMaster.getNewContainerId());

    CyclicBarrier barrier = new CyclicBarrier(parallelNum);

    for (int count = 0; count < parallelNum; count++) {
      containerIdFetcher.submit(() -> {
        try {
          barrier.await();
          while (times.incrementAndGet() < total) {
            mBlockMaster.getNewContainerId();
          }
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      });
    }

    containerIdFetcher.shutdown();
    containerIdFetcher.awaitTermination(6, TimeUnit.SECONDS);
    mBlockMaster.close();

    long journaledNextContainerId = mBlockMaster.getJournaledNextContainerId();

    assertTrue(journaledNextContainerId >= total);
    assertTrue(journaledNextContainerId <= total + containerIdReservationSize);
  }

  @Test
  public void stop() throws Exception {
    mRegistry.stop();
    assertTrue(mExecutorService.isShutdown());
    assertTrue(mExecutorService.isTerminated());
  }
}


text:
<?php namespace PhpNFe\NFe\Builder\Det\Imposto\ICMS;

/**
 * Grupo CRT=1 – Simples Nacional e
 * CSOSN = 500
 * Tributação ICMS pelo Simples Nacional, CSOSN=500 (v2.0).
 * Class ICMSSN500Nfe.
 */
class ICMSSN500Nfe extends \PhpNFe\Tools\Builder\Builder
{
    /**
     * Origem da mercadoria.
     * 0 - Nacional, exceto as indicadas nos códigos 3, 4, 5 e 8;
     * 1 - Estrangeira - Importação direta, exceto a indicada no código
     * 6;
     * 2 - Estrangeira - Adquirida no mercado interno, exceto a
     * indicada no código 7;
     * 3 - Nacional, mercadoria ou bem com Conteúdo de Importação
     * superior a 40% e inferior ou igual a 70%;
     * 4 - Nacional, cuja produção tenha sido feita em conformidade
     * com os processos produtivos básicos de que tratam as
     * legislações citadas nos Ajustes;
     * 5 - Nacional, mercadoria ou bem com Conteúdo de Importação
     * inferior ou igual a 40%;
     * 6 - Estrangeira - Importação direta, sem similar nacional,
     * constante em lista da CAMEX e gás natural;
     * 7 - Estrangeira - Adquirida no mercado interno, sem similar
     * nacional, constante lista CAMEX e gás natural.
     * 8 - Nacional, mercadoria ou bem com Conteúdo de Importação
     * superior a 70%;.
     * @var string
     * @max 1
     */
    public $orig = '';

    /**
     * Código de Situação da Operação –
     * Simples Nacional
     * 500=ICMS cobrado anteriormente por substituição tributária
     * (substituído) ou por antecipação. (v2.0).
     * @var string
     * @max 3
     */
    public $CSOSN = '';

    /**
     * Valor da BC do ICMS ST retido.
     * Valor da BC do ICMS ST cobrado anteriormente por ST (v2.0).
     * O valor pode ser omitido quando a legislação não exigir a sua
     * informação. (NT 2011/004).
     * @var float
     * @dec 2
     */
    public $vBCSTRet = 0.00;

    /**
     * Valor do ICMS ST retido.
     * Valor do ICMS ST cobrado anteriormente por ST (v2.0). O valor
     * pode ser omitido quando a legislação não exigir a sua
     * informação. (NT 2011/004).
     * @var float
     * @dec 2
     */
    public $vICMSSTRet = 0.00;
}


text:
import { start } from './core'

start()


text:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

	<item
		android:id="@+id/first"
		android:icon="@android:drawable/ic_media_previous"
		android:showAsAction="always"
		android:title="@string/first">
	</item>
  <item
    android:id="@+id/last"
    android:icon="@android:drawable/ic_media_next"
    android:showAsAction="always"
    android:title="@string/last">
  </item>
		<item
		android:id="@+id/present"
		android:checkable="true"
		android:checked="true"
		android:showAsAction="never"
		android:title="@string/show_presentation">
	</item>

</menu>


text:
<form action="{{ url_for('reset_with_token', token=token) }}" method="POST">
    {{ form.password.label }}: {{ form.password }}<br>
    {{ form.csrf_token }}
    <input type="submit" value="Change my password" />
</form>