Пример #1
0
VBIDecoder::~VBIDecoder()
{
    // If there's a subtitle image that hasn't been written to the XML file,
    // do it now.
    flushPage(currTimestamp);

    vbi_decoder_delete(decoder);
    vbi_export_delete(exporter);

    // Write the xml closing tags, and close the file
    fprintf(fpxml, "</stream>\n</subpictures>\n");
    fflush(fpxml);
    fclose(fpxml);

    if (fileIndex == 0)
    {
        // We didn't find any CC or Teletext data
        // Unlink the xml file, print an error message
        // and exit with non-zero exit code
        unlink(xmlfile);
        fflush(fplog);
        fprintf(stderr, "No CC or Teletext data found\n");
        fflush(stderr);
        exit(1);
    }
}
Пример #2
0
void MemoryMapped::map(uint64_t from)
{
    PageIndex pageIndex = mapCandidate();
    if (pageIndex == InvalidPage) {
        throw std::exception("Failed to map file, no candidate page.");
    }

    MemoryPage & page = m_Pages[pageIndex];
    if (!page.data()) {
        page.data() = reinterpret_cast<uint8_t*>(m_Allocator.getChunk(pageIndex));
    }

    if (page.dirty()) {
        flushPage(pageIndex);
    }

    // allign pages on pageSize so there are no overlaps
    from = (from / m_PageSize) * m_PageSize;

    uint64_t mapSize = std::min<uint64_t>(m_PageSize, m_FileSize - from);
    page.reset(from, mapSize);
    _fseeki64(m_File, from, SEEK_SET);

    if (fread(page.data(), 1, mapSize, m_File) != mapSize) {
        throw std::exception("Failed to map file in memory");
    }
    m_UsedPages = std::min<uint64_t>(m_UsedPages + 1, m_PageCount);
}
Пример #3
0
void printerStream::printText(const QString &txt, bool newLine)
{
    if (fwbdebug)
    {       
        qDebug("printText -------");
        qDebug("pageBody.height(): %d", pageBody.height());
        qDebug("yPos: %d", yPos);
    }

    if (txt.isEmpty()) return;
    if (printer->printerState() == QPrinter::Aborted) return;

    pr.setFont( bodyFont );
    QFontMetrics fm = pr.fontMetrics();
    QRect br = fm.boundingRect(txt);

    if (getYSpace()<br.height())
    {
        flushPage();
        beginPage();   // resets yPos
    }

    if (pageNo>=fromPage && pageNo<=toPage)
    {
        pr.setPen(Qt::black);
        pr.drawText( xmargin, yPos, printer->width()-2*xmargin, br.height(),
                     Qt::TextExpandTabs | Qt::TextDontClip,
                     txt );
    }
    int nlines=1;
    int i=-1;
    while ( (i=txt.indexOf("\n",i+1))>=0 ) nlines++;
    if (newLine) yPos = yPos + nlines*fm.lineSpacing();
}
Пример #4
0
bool QtopiaPrintEngine::newPage()
{
    flushPage();
    clearPage();
    ++(d_func()->pageNumber);
    return true;
}
Пример #5
0
void MemoryMapped::flush()
{
    for (PageIndex c = 0; c < m_PageCount; ++c) {
        if (m_Pages[c].dirty()) {
            flushPage(c);
        }
    }
}
Пример #6
0
void BufMgr::deleteFrame(int i)
{
	if (bufDescr[i]->dirty)
		flushPage(bufDescr[i]->pageNum);
	lhm->erase(bufDescr[i]->pageNum, bufDescr[i]->ts, bufDescr[i]->loved);
	assert(hashTable->erase(bufDescr[i]->pageNum) == 1);
	delete bufDescr[i];
}
Пример #7
0
void printerStream::printPixmap(const QPixmap &pm, bool newLine)
{
#if 0
    QPaintDevice *dev = pr.device();
    if (fwbdebug)
    {
        qDebug("printPixmap: width=%d height=%d", pm.width(), pm.height());
        qDebug("printPixmap: printer->resolution()=%d", printer->resolution());
        if (dev)
        {
            qDebug("printPixmap: device parameters:");
            qDebug("             height=%d width=%d",
                   dev->height(), dev->width());
            qDebug("             logicalDpiY=%d logicalDpiX=%d",
                   dev->logicalDpiY(), dev->logicalDpiX());
            qDebug("             physicalDpiY=%d physicalDpiX=%d",
                   dev->physicalDpiY(), dev->physicalDpiX());
        }
    }
#endif

    int target_w = (int)(pm.width() * pixmap_scaling_ratio);
    int target_h = (int)(pm.height() * pixmap_scaling_ratio);

    int pmYOffset = 0;
    while ( getYSpace()<(pm.height()-pmYOffset) )
    {
        int yFrag = pageBody.height() - yPos;
        if (pageNo>=fromPage && pageNo<=toPage)
        {
            if (fwbdebug)
                qDebug("Print pixmap 1: yPos=%d pmYOffset=%d "
                       "yFrag=%d target_w=%d target_h=%d",
                       yPos, pmYOffset, yFrag, target_w, target_h);
            pr.drawPixmap(xmargin, yPos, target_w, target_h,
                          pm,
                          0, pmYOffset, -1, yFrag);
        }
        pmYOffset = pmYOffset + yFrag;
        flushPage();
        beginPage();   // resets yPos
    }
    if (pageNo>=fromPage && pageNo<=toPage)
    {
        if (fwbdebug)
            qDebug("Print pixmap 2: yPos=%d pmYOffset=%d target_w=%d target_h=%d",
                   yPos, pmYOffset, target_w, target_h);
        pr.drawPixmap(xmargin, yPos, target_w, target_h,
                      pm,
                      0, pmYOffset, -1, -1);
    }

    if (newLine) yPos = yPos + (target_h - pmYOffset);
}
Пример #8
0
void
VBIDecoder::writePage(vbi_page* pg, Timestamp& startTS)
{
    if (*fileName != 0)
        flushPage(startTS);

    sprintf(fileName, "%ssub%04d.png", prefix, fileIndex++);
    startTimestamp = startTS;
    if (!vbi_export_file(exporter, fileName, pg))
    {
        fflush(fplog);
        fprintf(stderr, "vbi_export_file(file=%s) failed: %s\n",
            fileName, vbi_export_errstr(exporter));
        fflush(stderr);
        exit(1);
    }

    // Copy the page so checkPage can compare it against future pages
    memcpy(&lastPage, pg, sizeof(lastPage));

    fflush(fplog);
    textBytes = vbi_print_page_region(pg, textBuf, textSize, "UTF-8",
        TRUE, TRUE,
        region.mincol,  region.minrow,
        region.maxcol - region.mincol+1,
        region.maxrow - region.minrow+1);
    fflush(stderr);

    if (verbose)
    {
        fwrite(textBuf, textBytes, 1, fplog);
        putc('\n', fplog);
    }

    // Check for characters that spumux won't parse
    // null chars will be changed to space
    // pairs of dashes will be changed to underscores
    for (char* ptr = textBuf; ptr < textBuf+textBytes; ptr++)
    {
        switch (*ptr)
        {
            case 0:
                *ptr = ' ';
                break;
            case '-':
                if (*(ptr+1) == '-')
                {
                    *ptr++ = '_';
                    *ptr = '_';
                }
                break;
        }
    }
}
Пример #9
0
bool QtopiaPrintEngine::end()
{
    Q_D(QtopiaPrintEngine);

    d->paintEngine()->end();

    // Flush the last page.
    flushPage();

    // Output the fax data to a file (TODO: send to the print queuing daemon).
    QString filename;
    if ( !d->outputFileName.isEmpty() )
        filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/Documents/") + d->outputFileName;
    else
        filename = QString::fromLocal8Bit(qgetenv("HOME").constData()) + QLatin1String("/tmp/qwsfax.tiff");

    setProperty(QPrintEngine::PPK_OutputFileName, filename);
    QFile file( filename );
    if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) {
	qDebug( "Failed to open %s for printer output",
		filename.toLatin1().constData() );
    } else {
	file.write( d->buffer.data() );
	file.close();
    }

    // Free up the memory for the image buffer.
    d->buffer.clear();

    // Finalize the print job.
    d->printerState = QPrinter::Idle;

    // call qcop service
    QMap<QString, QVariant> map;
    for ( int x = 0; x <= QPrintEngine::PPK_Duplex; x++ )
        map.insert( QString::number(x), property((QPrintEngine::PrintEnginePropertyKey)(x)));
    QVariant variant(map);

    QByteArray data;
    QDataStream out(&data, QIODevice::WriteOnly);
    out << variant;
    QCopChannel::send(QLatin1String("QPE/Service/Print"), QLatin1String("print(QVariant)"), data);

    return true;
}
Пример #10
0
Status BufMgr::flushAllPages(){
	int* z = new int[numbuf];
	for (int i = 0; i < numbuf; i++)
		z[i] = 1;
	for (int i = 0; i < freeFrames.size(); i++)
		z[freeFrames[i]] = 0;
	for (int i = 0; i < numbuf; i++)
		if (z[i] && bufDescr[i]->dirty)
		{
			Status s = flushPage(bufDescr[i]->pageNum);
			if (s != OK)
			{
				MINIBASE_CHAIN_ERROR(BUFMGR, s);
				return s;
			}
		}
  return OK;
}
Пример #11
0
int squash(Buffer * buf) {
   int num;
   for (num = 0; num < buf->nBufferBlocks; num++) {
      if (buf->pin[num] == 1) {
         unPinPage(buf, buf->pages[num].address);
      }
      if (buf->dirty[num] == 1) {
         flushPage(buf, buf->pages[num].address);
      }
   }

   free(buf->database);
   free(buf->pages);
   free(buf->cache);
   free(buf->buffer_timestamp);
   free(buf->cache_timestamp);
   free(buf->pin);
   free(buf->dirty);
   free(buf->volatileFDs);
   free(buf->persistentFDs);
   free(buf);

   return tfs_unmount();
}
Пример #12
0
void printerStream::printQTable(QTableView *tbl, bool left_margin,
                                bool top_margin)
{
    if (fwbdebug)
    {
        qDebug("printQTable ----------------------------------------------");
        qDebug("Size: %dx%d", tbl->width(), tbl->height());
//        qDebug("Visible: %dx%d",
//               tbl->contentsRect().width(), tbl->contentsRect().height());
//        qDebug("Viewport: %dx%d",
//               tbl->viewport()->width(), tbl->viewport()->height());
//        qDebug("pageBody.height(): %d", pageBody.height());
        qDebug("YSpace: %d", getYSpace());
        qDebug("yPos: %d", yPos);
    }

    int top_row = 0;
    int bottom_row = 1;

    int columnsWidth = 0;
    int i = 0;
    while (i < tbl->model()->columnCount())
    {
        columnsWidth += tbl->columnWidth(i);
        i++;
    }

    int rowCount = tbl->model()->rowCount();
    while (top_row <= (rowCount-1))
    {
        int row = 0;

        int tblHeight = (int)(
            (float)(tbl->horizontalHeader()->height()) * pixmap_scaling_ratio);

        /* ===================================================================
         * Row height is screen pixels, getYSpace returns remaining
         * space in printer resolution units. Keep track of both to
         * resize pixmap
         * ===================================================================
         */
        int pixMapHeight = tbl->horizontalHeader()->height();
        for (row=top_row; row < rowCount; ++row)
        {
            if (tbl->isRowHidden(row))
            {
                // hidden rows count but do not contribute to table height
                continue;
            }

            int nth = tblHeight +
                (int)((float)(tbl->rowHeight(row)) * pixmap_scaling_ratio);

            if ( nth==getYSpace() )  break;

            if ( nth>getYSpace() ) 
            { 
                row--; 
                break; 
            }

            tblHeight = nth;
            pixMapHeight += tbl->rowHeight(row);
        }
        
        // if row < top_row then even single row does not fit on the page
        if (row < top_row)
        {
            row = top_row;
            pixMapHeight = tbl->rowHeight(top_row);
        }

        if (row == rowCount) row--;

        bottom_row = row;

        int left_hdr_w = 0;
        if (left_margin && tbl->verticalHeader() != NULL)
            left_hdr_w = tbl->verticalHeader()->width();

        int top_hdr_h = 0;
        if (top_margin && tbl->horizontalHeader() != NULL)
            top_hdr_h = tbl->horizontalHeader()->height();

        int tblWidth = columnsWidth + left_hdr_w;

        if (fwbdebug)
            qDebug("Page %d -- (%d-%d of %d rows) tblWidth: %d   tblHeight: %d",
                   pageNo, top_row, bottom_row, rowCount, tblWidth, tblHeight);

        tbl->resize(tblWidth, pixMapHeight);

        tbl->verticalHeader()->resize(
            tbl->verticalHeader()->width(),
            tbl->height() - tbl->horizontalHeader()->height());
        tbl->horizontalHeader()->resize(
            tbl->width() - tbl->verticalHeader()->width(),
            tbl->horizontalHeader()->height());


// QTableView::scrollTo() makes row visible, but if there are not enough
// rows below it, it appears in the middle of the table. This means the table
// shows few rows that belong on the previous page, which is bad.
//
//        tbl->scrollTo(tbl->model()->index(top_row, 0),
//                      QAbstractItemView::PositionAtTop);

        int top_row_position = tbl->verticalHeader()->sectionPosition(top_row);
        tbl->verticalHeader()->setOffset(top_row_position);

        tbl->update();


        printPixmap(QPixmap::grabWidget(tbl));  //,0,0,-1,pixMapHeight));

        if (bottom_row>=(rowCount-1)) break;

        flushPage();
        beginPage();

        top_row = bottom_row + 1;

    }
}
Пример #13
0
void printerStream::printRuleSetView(RuleSetView *tbl, bool top_margin)
{
    if (fwbdebug)
    {
        qDebug("printQTable ----------------------------------------------");
        qDebug("Size: %dx%d", tbl->width(), tbl->height());
        qDebug("YSpace: %d", getYSpace());
        qDebug("yPos: %d", yPos);
    }

    int columnsWidth = 0;
    int i = 0;

    while (i < tbl->model()->columnCount())
    {
        columnsWidth += tbl->columnWidth(i);
        i++;
    }

    RuleSetModelIterator it = ((RuleSetModel*)tbl->model())->begin();
    RuleSetModelIterator end = ((RuleSetModel*)tbl->model())->end();

    RuleSetModelIterator bottomIt;

    while (it.isValid() && it != end)
    {
        // Pages iterations

        int tblHeight = (int)(
            (float)(tbl->header()->height()) * pixmap_scaling_ratio);

        /* ===================================================================
         * Row height is screen pixels, getYSpace returns remaining
         * space in printer resolution units. Keep track of both to
         * resize pixmap
         * ===================================================================
         */
        int pixMapHeight = tbl->header()->height();


        RuleSetModelIterator pit = it;
        while (pit != end)
        {

            // Check if current index is collapsed
            QModelIndex index = pit.index();
            QModelIndex parent = index.parent();
            if (!parent.isValid() || tbl->isExpanded(parent))
            {

                int nth = tblHeight +
                    (int)((float)(tbl->rowHeight(index)) * pixmap_scaling_ratio);

                if ( nth==getYSpace() )  break;

                if ( nth>getYSpace() )
                {
                    // if it == pit then even single row does not fit on the page
                    if (it == pit)
                    {
                        pixMapHeight = tbl->rowHeight(index);
                    } else
                    {
                        --pit;
                    }
                    break;
                }

                tblHeight = nth;
                pixMapHeight += tbl->rowHeight(index);
            }

            ++pit;
        }

        bottomIt = pit;

        int left_hdr_w = 0;

        int top_hdr_h = 0;
        if (top_margin && tbl->header() != NULL)
            top_hdr_h = tbl->header()->height();

        int tblWidth = columnsWidth + left_hdr_w;


            qDebug("Page %d -- tblWidth: %d   tblHeight: %d",
                   pageNo, tblWidth, tblHeight);

        tbl->resize(tblWidth, pixMapHeight);
        tbl->updateWidget();

        tbl->scrollTo(it.index(), QAbstractItemView::PositionAtTop);

        printPixmap(QPixmap::grabWidget(tbl));

        if (bottomIt == end) break;

        flushPage();
        beginPage();

        it = bottomIt;
        ++it;
    }
}
Пример #14
0
void DataTerminal::processByte(uint8_t byte)
{
    switch(mState) {
        case STATE_WAITING:
            if ( byte == START_TRANSFER_CMD ) {
                mState = STATE_IN_TRANSFER_HEADER;
                mByteCount = 0;
                trace_printf("Receiving metadata\n");
                GPIO_SetBits(GPIOB, GPIO_Pin_14);
                writeCmd(ACK);
            }
            else {
                trace_printf("Bad command: %.2x\n", byte);
                fail();
            }
            break;
        case STATE_IN_TRANSFER_HEADER: {
            //trace_printf("1 byte\n");
            char *p = (char*)&mMetadata;
            memcpy(p + mByteCount, &byte, 1);
            ++mByteCount;
            if ( mByteCount == sizeof mMetadata ) {
                trace_printf("Magick: %.8x\n", mMetadata.magic);
                // Is the metadata sane?
                if ( mMetadata.magic == METADATA_MAGIC ) {
                    mState = STATE_IN_TRANSFER_BLOCK;
                    trace_printf("Expecting %d bytes\n", mMetadata.size);
                    printmd5(mMetadata.md5);
                    GPIO_SetBits(GPIOB, GPIO_Pin_14);
                    mByteCount = 0;
                    mWriteAddress = APPLICATION_ADDRESS;
                    MD5Init(&mMD5);
                    unlockFlash();
                    writeCmd(ACK);
                }
                else {
                    trace_printf("Bad metadata \n");
                    fail();
                }
            }
            }
            break;
        case STATE_IN_TRANSFER_BLOCK:
            MD5Update(&mMD5, &byte, 1);
            if ( mByteCount == 0 ) {
                GPIO_SetBits(GPIOB, GPIO_Pin_15);
            }

            size_t offset = mByteCount % FLASH_PAGE_SIZE;
            assert(offset < sizeof mCurrPage);
            memcpy(mCurrPage + offset, &byte, 1);

            ++mByteCount;

            if ( mByteCount % FLASH_PAGE_SIZE == 0 ) {
                flushPage();
            }

            // Acknowledge every 1K
            if ( mByteCount % 1024 == 0 ) {
                trace_printf("Sending ACK\n");
                writeCmd(ACK);
            }


            if ( mByteCount == mMetadata.size ) {
                if ( mMetadata.size % 1024 ) {
                    // We have a partial page to write
                    flushPage();
                    writeCmd(ACK);
                }

                // Last byte!
                trace_printf("Received %d bytes\n", mMetadata.size);
                GPIO_ResetBits(GPIOB, GPIO_Pin_14);
                mState = STATE_WAITING;

                uint8_t d[16];
                MD5Final(d, &mMD5);
                printmd5(d);
                if ( memcmp(d, mMetadata.md5, 16) ) {
                    // Bad MD5
                    trace_printf("MD5 mismatch :( \n");
                    fail();
                }
                else {
                    // Good transfer
                    trace_printf("MD5 match :) \n");
                    writeCmd(ACK);


                    flushMetadata();
                    lockFlash();
                    NVIC_SystemReset();
                }
            }
            break;
    }
}
Пример #15
0
/* returns the index in the buffer array */
int readPage(Buffer * buf, DiskAddress diskPage) {
   int num, available = 0, toEvict; /* available is set to 1 if there are any unpinned pages */
   long oldest = -1;
   /* check if this file has been opened before in persistent */
   if (checkPersistentFiles(buf, diskPage.FD) == -1) {
      buf->numPersistentFiles += 1;
      buf->persistentFDs = (int *)realloc(buf->persistentFDs, sizeof(int) * buf->numPersistentFiles);
      buf->persistentFDs[buf->numPersistentFiles-1] = diskPage.FD;
   }

   /* buffer check for page */
   for (num = 0; num < buf->nBufferBlocks; num++) {
      if (buf->buffer_timestamp[num] != -1 && buf->pages[num].address.FD == diskPage.FD && buf->pages[num].address.pageId == diskPage.pageId) { /* found page in buffer */
         buf->buffer_timestamp[num] = time(NULL); 
         return num;
      }
   }

   /* if this is reached, then the page is not in the buffer */
   num = findEmpty(buf);
   if (num != -1) {
      /* bring page to buffer */
      tfs_readPage(diskPage.FD, diskPage.pageId, 
                  (unsigned char *)buf->pages[num].block);

      /* sets page metadata */
      buf->pages[num].address = diskPage; 
      buf->buffer_timestamp[num] = time(NULL);         
      
      buf->numBufferOccupied++;
      return num;
   }
   
   /* 
    * Implement LRU eviction.
    * all pageslots are full, check if they're all pinned 
    */
   for (num = 0; num < buf->nBufferBlocks; num++) {
      if(buf->pin[num] == 0) { /* if the page is unpinned */
         if (oldest == -1) { /* initial timestamp */
            oldest = buf->buffer_timestamp[num];
            toEvict = num;
         }
         else if (oldest > buf->buffer_timestamp[num]) { /* found an older time stamp */
            oldest = buf->buffer_timestamp[num];
            toEvict = num;
         }
         available = 1;
      }
   }
   if (available == 0) { /* all the pages are pinned */
      return -1; /* error */
   }
   /* at this point a page needs to be evicted */
   flushPage(buf, buf->pages[toEvict].address);
   /* bring page to buffer */
   tfs_readPage(diskPage.FD, diskPage.pageId, (unsigned char *)buf->pages[toEvict].block);
   /* set other bits*/
   buf->pages[toEvict].address = diskPage;
   buf->buffer_timestamp[toEvict] = time(NULL); 
   
   return toEvict;
}
Пример #16
0
void
VBIDecoder::checkPage(vbi_page* pg)
{
    // Check for blank page,
    // filling in region to non-blank bounds
    region.mincol = pg->columns;
    region.maxcol = 0;
    region.minrow = pg->rows;
    region.maxrow = 0;
    int nonEmpty = 0;
    int fg = 7;
    int bg = 0;

    vbi_char* text = pg->text;

    for (int row = 0; row < pg->rows; row++)
    {
        for (int col = 0; col < pg->columns; col++, text++)
        {
            if (text->opacity != VBI_TRANSPARENT_SPACE)
            {
                nonEmpty++;
                if (region.mincol > col)
                    region.mincol = col;
                if (region.maxcol < col)
                    region.maxcol = col;
                if (region.minrow > row)
                    region.minrow = row;
                if (region.maxrow < row)
                    region.maxrow = row;
                if (verbose && (text->foreground != fg || text->background != bg))
                {
                    fg = text->foreground;
                    bg = text->background;
                    fprintf(fplog, "Color change at %dx%d fg=%d bg=%d\n", col, row, fg, bg);
                }
            }
        }
    }

    if (nonEmpty == 0)
    {
        if (verbose)
            fprintf(fplog, "Blank page\n");
        flushPage(currTimestamp);
        return;
    }

    // If we haven't flushed the last page,
    // compare it against the current page
    if (fileName != 0)
    {
        if (memcmp(lastPage.text, pg->text, sizeof(lastPage.text)) == 0)
        {
            if (verbose)
                fprintf(fplog, "Identical pages\n");
            return;
        }
    }
    writePage(pg, currTimestamp);
}
Пример #17
0
int allocateCachePage(Buffer *buf, DiskAddress diskpage){
       int i, bufIndex, oldestCache = 0, oldestBuf = -1;
       
       /* check if this file has been opened before in volatile */
   if (checkVolatileFiles(buf, diskpage.FD) == -1) {
      buf->numVolatileFiles += 1;
      buf->volatileFDs = (int *)realloc(buf->volatileFDs, sizeof(int) * buf->numVolatileFiles);
      buf->volatileFDs[buf->numVolatileFiles-1] = diskpage.FD;
   }

   /* check if this page is already in cache */
   i = findPageVolatile(buf, diskpage);
   if (i != -1)
      return i;

   /* check if this page is already in persistent buffer */
   bufIndex = findPage(buf, diskpage);
   
       
       //Check if cache is full
       if(buf->nCacheBlocks == buf->numCacheOccupied){
             
             //Find index of least recently used for eviction
             for(i = 0; i < buf->nCacheBlocks; i++){
                  if(buf->cache_timestamp[oldestCache] > buf->cache_timestamp[i]) {
                        oldestCache = i;
                  }
             }
             buf->cache_timestamp[oldestCache] = -1;
             
             //Check if buffer is full
             if(buf->nBufferBlocks == buf->numBufferOccupied){
                  //If it is full find the least recently used unpinned page and write to disk
                  for(i = 0; i < buf->nBufferBlocks; i++){
                       if(buf->pin[i] == 0 &&
                        (oldestBuf == -1 || buf->buffer_timestamp[oldestBuf] > buf->buffer_timestamp[i])) {
                              oldestBuf = i;
                       }
                  }
                  if (oldestBuf == -1) // all pages were pinned
                     return -1;
                  writePage(buf, buf->pages[oldestBuf].address);
                  flushPage(buf, buf->pages[oldestBuf].address);
             } else {
                  //If it is not full then find empty spot and insert into buffer
                  for(i = 0; i < buf->nBufferBlocks; i++){
                        if(buf->buffer_timestamp[i] == -1){
                              oldestBuf = i;
                              buf->numBufferOccupied++;
                              buf->buffer_timestamp[i] = time(NULL);
                              break;
                        }
                  }
             }
             
             //Copy the block from the cache into the buffer
             memcpy(&(buf->pages[oldestBuf]), &(buf->cache[oldestCache]), sizeof(Block));
             
             
             buf->pin[oldestBuf] = 1;
       }
       
       //Write the diskapage passed into the now open cache spot
       for(i = 0; i < buf->nCacheBlocks; i++){
             if(buf->cache_timestamp[i] == -1){
                   buf->cache[i].address.pageId = diskpage.pageId;
                   buf->cache[i].address.FD = diskpage.FD;
                   buf->numCacheOccupied++;
                   buf->cache_timestamp[i] = time(NULL); 

                   /* if page was already in persistent buffer, copy its data into this cache spot */
                   if (bufIndex != -1) {
                        memcpy(buf->cache[i].block, &buf->pages[bufIndex].block, BLOCKSIZE);

                        /* remove page from persistent buffer */
                        buf->buffer_timestamp[bufIndex] = -1;
                        buf->pin[bufIndex] = 0;
                        buf->numBufferOccupied--;
                   }

                   break;
             }
       }
       return i;
 }