Exemple #1
0
bool FlashDevice::comparePage(const void* data, flash_addr_t address, page_size_t length) {
    uint8_t buf[STACK_BUFFER_SIZE];
    page_size_t offset = 0;
    while (offset<length) {
        page_size_t toRead = min(sizeof(buf), length-offset);
        if (!readPage(buf, address+offset, toRead))
            break;
        if (!memcmp(buf, as_bytes(data)+offset, toRead))
            break;
        offset += toRead;
    }
    return offset==length;
}
Exemple #2
0
// Given the offset of the "current" page, find the page immediately preceding
// it (if any) and return its granule position.
// To do this we back up from the "current" page's offset until we find any
// page preceding it and then scan forward to just before the current page.
status_t MyVorbisExtractor::findPrevGranulePosition(
        off64_t pageOffset, uint64_t *granulePos) {
    *granulePos = 0;

    off64_t prevPageOffset = 0;
    off64_t prevGuess = pageOffset;
    for (;;) {
        if (prevGuess >= 5000) {
            prevGuess -= 5000;
        } else {
            prevGuess = 0;
        }

        LOGV("backing up %lld bytes", pageOffset - prevGuess);

        status_t err = findNextPage(prevGuess, &prevPageOffset);
        if (err != OK) {
            return err;
        }

        if (prevPageOffset < pageOffset || prevGuess == 0) {
            break;
        }
    }

    if (prevPageOffset == pageOffset) {
        // We did not find a page preceding this one.
        return UNKNOWN_ERROR;
    }

    LOGV("prevPageOffset at %lld, pageOffset at %lld",
         prevPageOffset, pageOffset);

    for (;;) {
        Page prevPage;
        ssize_t n = readPage(prevPageOffset, &prevPage);

        if (n <= 0) {
            return (status_t)n;
        }

        prevPageOffset += n;

        if (prevPageOffset == pageOffset) {
            *granulePos = prevPage.mGranulePosition;
            return OK;
        }
    }
}
Exemple #3
0
page_id_t
TPIO::RebaseTPIOTxSession::rebaseForceVisit(page_id_t pgid)
{
	m_visited.insert(pgid);
	
#ifdef VERBOSE_REBASE
	std::cout << "rebase visit pgid: " << pgid << std::endl;
#endif

	Page pg(readPage(pgid));

	mod_info_t mod;
	pg.updateLinks(&mod, this);
	
	return mod.isValid() ? mod.idOvr : pgid;
}
Exemple #4
0
//junliang.zhou 2011.12.13 20:40 add
uint64_t MyVorbisExtractor::findLastGranule(void) {   
		Page prevPage, curPage;
		off_t prevPageOffset;
		for ( prevPageOffset = 0; ; ) 
		{
			ssize_t n = readPage(prevPageOffset, &curPage);
			if (n <= 0) 
			{ 
				break; 

			} else
				prevPage = curPage;
			prevPageOffset += n;
		} 
		return prevPage.mGranulePosition; 
	}
    std::vector<unsigned char> TopazCommands::readPages(int start_page, int stop_page)
    {
		std::vector<unsigned char> ret;

        if (start_page > stop_page)
        {
            THROW_EXCEPTION_WITH_LOG(std::invalid_argument, "Start page can't be greater than stop page.");
        }

        for (int i = start_page; i <= stop_page; ++i)
        {
            std::vector<unsigned char> data = readPage(i);
			ret.insert(ret.end(), data.begin(), data.end());
        }

        return ret;
    }
void KeyFile::dump(FILE *f, int flags) {
  KeyFileHeader header;

  readHead(header, false);
  KeyPage page(m_pageInfo);
  dbAddrDump(header.m_root, 1,f,flags);
  if(flags & DUMP_HEADER) {
    _ftprintf(f,_T("Root:%s Last:%s Freelist:("), toString(header.m_root).cstr(), toString(header.m_last).cstr());
  }
  if(flags & DUMP_FREELIST) {
    for(KeyPageAddr list = header.m_freeList;list != DB_NULLADDR; list = page.getNextFree()) {
      _ftprintf(f,_T("%s "),toString(list).cstr());
      readPage(list, page);
    }
    _ftprintf(f,_T(")\n"));
  }
}
Exemple #7
0
int32_t * FileSystem::getFilePageMapping(int *arraySize) {
	bool mustReleaseLock = getLock();

	int32_t *result = (int32_t*)malloc(fileMappingSize * doubleIntsPerPage * INT_SIZE);
	int32_t *buffer = (int32_t*)malloc(pageSize);
	int cnt = 0;
	for (int i = 0; i < fileMappingSize; i++) {
		readPage(pageCount + pageLayoutSize + i, buffer);
		for (int k = 0; k < doubleIntsPerPage; k++)
			result[cnt++] = buffer[k + k];
	}
	free(buffer);
	*arraySize = fileMappingSize * doubleIntsPerPage;

	if (mustReleaseLock)
		releaseLock();
	return result;
} // end of getFilePageMapping(int*)
Exemple #8
0
int newPage(Buffer *buf, fileDescriptor FD, DiskAddress *diskPage) {
   // if everything is pinned, return -1
   int i;
   for (i = 0; i < buf->nBufferBlocks; i++) {
      if (!buf->pin[i])
         break;
   }
   if (i == buf->nBufferBlocks)
      return -1;

   diskPage->FD = FD;
   diskPage->pageId = tfs_numPages(FD);
   char *data = (char *)calloc(BLOCKSIZE, 1);
   tfs_writePage(FD, diskPage->pageId, (unsigned char *)data);
   free(data);

   return readPage(buf, *diskPage);
}
Exemple #9
0
status_t MyVorbisExtractor::findGranulePositionofPage(off64_t offset,uint64_t *granulePositionofPage)
{
	 if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) {
        // Once we know where the actual audio data starts (past the headers)
        // don't ever seek to anywhere before that.
        offset = mFirstDataOffset;
    }
   if(((uint64_t)offset) == mFileSize)
   	{
   		findPrevGranulePosition(mFileSize, granulePositionofPage);
   		if((*granulePositionofPage) < 0xFFFFFFFFFFFF)
   		  return OK;
   		else 
   		  return UNKNOWN_ERROR;    		
   	}
   	
    off64_t pageOffset;
    status_t err = findNextPage_l(offset, &pageOffset);

    if (err != OK) {
    	  err = findNextPage(offset, &pageOffset);
    	  if((err == OK) && (offset == pageOffset))
    	  {
    	  	Page page;
          readPage(offset, &page);
          *granulePositionofPage = page.mGranulePosition;
    	  }
    	  else
    	    findPrevGranulePosition(mFileSize, granulePositionofPage);
   		  if((*granulePositionofPage) < 0xFFFFFFFFFFFF)
   		    return OK;
   		  else 
   			return UNKNOWN_ERROR; 
    }
    // We found the page we wanted to seek to, but we'll also need
    // the page preceding it to determine how many valid samples are on
    // this page.
    findPrevGranulePosition(pageOffset, granulePositionofPage);
 		if((*granulePositionofPage) < 0xFFFFFFFFFFFF)
   		  return OK;
 		else 
   	      return UNKNOWN_ERROR; 
}
Exemple #10
0
	int Buffer::acquirePage(TransactionID* tid, PagePointer* pp)
	{
		int retval;

		if (!started)
			return -1;

		::pthread_mutex_lock(&dbwriter.mutex);

		if (tid != NULL) {
			Statistics::get_statistics(pthread_self()).
				addPageReads(tid->getSessionId(), tid->getId(), 1);
		} else {
			Statistics::get_statistics(pthread_self()).
				addPageReads(-1, -1, 1);
		}
		buffer_addr_t buffer_addr = make_pair(pp->getFileID(), pp->getPageID());
		buffer_hash_t::iterator it = buffer_hash.find(buffer_addr);
		buffer_page* n_page;

		if (it != buffer_hash.end() && (*it).second.haspage) {
			n_page = &((*it).second);
			n_page->lock++;

			::pthread_mutex_unlock(&dbwriter.mutex);
			return 0;
		} else if (it != buffer_hash.end()) {
			if ((retval = readPage(tid, pp->getFileID(), pp->getPageID(), n_page)) != 0) {
				::pthread_mutex_unlock(&dbwriter.mutex);
				return retval;
			}

			n_page->lock++;
			(*it).second = *n_page;
			pp->setPage(n_page->page);

			::pthread_mutex_unlock(&dbwriter.mutex);
			return 0;
		} else {
			::pthread_mutex_unlock(&dbwriter.mutex);
			return -1;
		}
	};
Exemple #11
0
bool YaffsControl::readImage() {
    int result = 0;
    memset(&mReadInfo, 0, sizeof(YaffsReadInfo));
    if (mImageFile) {
        while (result == 0) {
            result = readPage();
            if (result == -1) {
                if (feof(mImageFile)) {
                    mReadInfo.eofHasIncompletePage = true;
                    result = 1;
                }
                break;
            }
            processPage();
        }
    }
    mReadInfo.result = (result == 1);
    mObserver->readComplete();
    return mReadInfo.result;
}
int main(void)
{
  int ret;
  int fd;
  int tries = 0;
  int tagIdLen = MAX_TAG_ID_LENGTH;
  unsigned char tagId[MAX_TAG_ID_LENGTH];

  bcm2835_init();

#if 0 // We're assuming the caller has made sure there's a tag present
  /* Check for the tag a few times before giving up */
  while ((tries < 10) && (!checkForTag(fd, tagId, &tagIdLen)))
  {
    tries++;
    tagIdLen = MAX_TAG_ID_LENGTH;
    usleep(50000);
  }
 
  if (tries < 10)
#endif
  {
    /* We found a tag! */
    int page = 4; // skip the first four pages as they hold general info on the tag
    int pageLen = MAX_TAG_ID_LENGTH;
    unsigned char pageData[MAX_TAG_ID_LENGTH];
    while (readPage(fd, page, pageData, &pageLen))
    {
      int j;
      for (j = 0; j < pageLen; j++)
      {
#if DEBUG
        printf("%02x", pageData[j]);
#else
        printf("%c", pageData[j]);
#endif
      }
      page++; // move onto the next page
    }
  }   
}
// Given the offset of the "current" page, find the page immediately preceding
// it (if any) and return its granule position.
// To do this we back up from the "current" page's offset until we find any
// page preceding it and then scan forward to just before the current page.
uint64_t MyVorbisExtractor::findPrevGranulePosition(off_t pageOffset) {
    off_t prevPageOffset = 0;
    off_t prevGuess = pageOffset;
    for (;;) {
        if (prevGuess >= 5000) {
            prevGuess -= 5000;
        } else {
            prevGuess = 0;
        }

        LOGV("backing up %ld bytes", pageOffset - prevGuess);

        CHECK_EQ(findNextPage(prevGuess, &prevPageOffset), (status_t)OK);

        if (prevPageOffset < pageOffset || prevGuess == 0) {
            break;
        }
    }

    if (prevPageOffset == pageOffset) {
        // We did not find a page preceding this one.
        return 0;
    }

    LOGV("prevPageOffset at %ld, pageOffset at %ld", prevPageOffset, pageOffset);

    for (;;) {
        Page prevPage;
        ssize_t n = readPage(prevPageOffset, &prevPage);

        if (n <= 0) {
            return 0;
        }

        prevPageOffset += n;

        if (prevPageOffset == pageOffset) {
            return prevPage.mGranulePosition;
        }
    }
}
Exemple #14
0
fs_pageno FileSystem::getPageStatus(fs_pageno page) {
	bool mustReleaseLock = getLock();
	fs_pageno result = FILESYSTEM_ERROR;

	int pageInTable, pageToRead, offsetInPage;

	if ((page < 0) || (page >= pageCount))
		goto endOfGetPageStatus;

	pageInTable = page / intsPerPage;
	pageToRead = pageCount + pageInTable;
	offsetInPage = (page % intsPerPage) * INT_SIZE;

	if (readPage(pageToRead, offsetInPage, INT_SIZE, &result) == FILESYSTEM_ERROR)
		goto endOfGetPageStatus;

endOfGetPageStatus:
	if (mustReleaseLock)
		releaseLock();
	return result;
} // end of getPageStatus(fs_pageno)
Exemple #15
0
fs_pageno FileSystem::getPageCount(fs_fileno fileHandle) {
	bool mustReleaseLock = getLock();
	fs_pageno result = FILESYSTEM_ERROR;

	int pageInTable, pageToRead, offsetInPage;

	if ((fileHandle < 0) || (fileHandle >= fileMappingSize * doubleIntsPerPage))
		goto endOfGetPageCount;

	pageInTable = fileHandle / doubleIntsPerPage;
	pageToRead = pageCount + pageLayoutSize + pageInTable;
	offsetInPage = (fileHandle % doubleIntsPerPage) * 2 * INT_SIZE + INT_SIZE;

	if (readPage(pageToRead, offsetInPage, INT_SIZE, &result) == FILESYSTEM_ERROR)
		goto endOfGetPageCount;

endOfGetPageCount:
	if (mustReleaseLock)
		releaseLock();
	return result;
} // end of getPageCount(fs_fileno)
Exemple #16
0
void MyVorbisExtractor::buildTableOfContents() {
    off64_t offset = mFirstDataOffset;
    Page page;
    ssize_t pageSize;
    while ((pageSize = readPage(offset, &page)) > 0) {
        mTableOfContents.push();

        TOCEntry &entry =
            mTableOfContents.editItemAt(mTableOfContents.size() - 1);

        entry.mPageOffset = offset;
        entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate;

        offset += (size_t)pageSize;
    }

    // Limit the maximum amount of RAM we spend on the table of contents,
    // if necessary thin out the table evenly to trim it down to maximum
    // size.

    static const size_t kMaxTOCSize = 8192;
    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);

    size_t numerator = mTableOfContents.size();

    if (numerator > kMaxNumTOCEntries) {
        size_t denom = numerator - kMaxNumTOCEntries;

        size_t accum = 0;
        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
            accum += denom;
            if (accum >= numerator) {
                mTableOfContents.removeAt(i);
                accum -= numerator;
            }
        }
    }
}
Exemple #17
0
status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
    *out = NULL;

    MediaBuffer *buffer = NULL;
    int64_t timeUs = -1;

    for (;;) {
        size_t i;
        size_t packetSize = 0;
        bool gotFullPacket = false;
        for (i = mNextLaceIndex; i < mCurrentPage.mNumSegments; ++i) {
            uint8_t lace = mCurrentPage.mLace[i];

            packetSize += lace;

            if (lace < 255) {
                gotFullPacket = true;
                ++i;
                break;
            }
        }

        if (mNextLaceIndex < mCurrentPage.mNumSegments) {
            off64_t dataOffset = mOffset + 27 + mCurrentPage.mNumSegments;
            for (size_t j = 0; j < mNextLaceIndex; ++j) {
                dataOffset += mCurrentPage.mLace[j];
            }

            size_t fullSize = packetSize;
            if (buffer != NULL) {
                fullSize += buffer->range_length();
            }
            MediaBuffer *tmp = new MediaBuffer(fullSize);
            if (buffer != NULL) {
                memcpy(tmp->data(), buffer->data(), buffer->range_length());
                tmp->set_range(0, buffer->range_length());
                buffer->release();
            } else {
                // XXX Not only is this not technically the correct time for
                // this packet, we also stamp every packet in this page
                // with the same time. This needs fixing later.

                if (mVi.rate) {
                    // Rate may not have been initialized yet if we're currently
                    // reading the configuration packets...
                    // Fortunately, the timestamp doesn't matter for those.
                    timeUs = mCurrentPage.mGranulePosition * 1000000ll / mVi.rate;
                }
                tmp->set_range(0, 0);
            }
            buffer = tmp;

            ssize_t n = mSource->readAt(
                    dataOffset,
                    (uint8_t *)buffer->data() + buffer->range_length(),
                    packetSize);

            if (n < (ssize_t)packetSize) {
                LOGV("failed to read %d bytes at 0x%016llx, got %ld bytes",
                     packetSize, dataOffset, n);
                return ERROR_IO;
            }

            buffer->set_range(0, fullSize);

            mNextLaceIndex = i;

            if (gotFullPacket) {
                // We've just read the entire packet.

                if (timeUs >= 0) {
                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
                }

                if (mFirstPacketInPage) {
                    buffer->meta_data()->setInt32(
                            kKeyValidSamples, mCurrentPageSamples);
                    mFirstPacketInPage = false;
                }

                *out = buffer;

                return OK;
            }

            // fall through, the buffer now contains the start of the packet.
        }

        CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);

        mOffset += mCurrentPageSize;
        ssize_t n = readPage(mOffset, &mCurrentPage);

        if (n <= 0) {
            if (buffer) {
                buffer->release();
                buffer = NULL;
            }

            LOGV("readPage returned %ld", n);

            return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
        }

        mCurrentPageSamples =
            mCurrentPage.mGranulePosition - mPrevGranulePosition;
        mFirstPacketInPage = true;

        mPrevGranulePosition = mCurrentPage.mGranulePosition;

        mCurrentPageSize = n;
        mNextLaceIndex = 0;

        if (buffer != NULL) {
            if ((mCurrentPage.mFlags & 1) == 0) {
                // This page does not continue the packet, i.e. the packet
                // is already complete.

                if (timeUs >= 0) {
                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
                }

                buffer->meta_data()->setInt32(
                        kKeyValidSamples, mCurrentPageSamples);
                mFirstPacketInPage = false;

                *out = buffer;

                return OK;
            }
        }
    }
}
Exemple #18
0
/*
 * getTableInfo -- 表のデータ定義情報を取得する関数
 *
 * 引数:
 *	tableName: 情報を表示する表の名前
 *
 * 返り値:
 *	tableNameのデータ定義情報を返す
 *	エラーの場合には、NULLを返す
 *
 * ***注意***
 *	この関数が返すデータ定義情報を収めたメモリ領域は、不要になったら
 *	必ずfreeTableInfoで解放すること。
 */
TableInfo *getTableInfo(char *tableName)
{
    File *file;
    TableInfo *tableinfo;
    char page[PAGE_SIZE];
    char *p;
    int num;
    char name[MAX_FIELD_NAME];
    DataType data;
    int i;

    /* tableFileName.[DEF_FILE_EXT]という文字列を作る*/
    char tableFileName[MAX_FILENAME+10];
    int len = strlen(tableName) + strlen(DEF_FILE_EXT) + 1;

    memset(tableFileName, '\0', strlen(tableFileName));
    snprintf(tableFileName, len, "%s%s", tableName, DEF_FILE_EXT);

    /*tableinfoをmalloc*/
    tableinfo = malloc(sizeof(TableInfo));
    if(tableinfo == NULL){
        printErrorMessage(ERR_MSG_MALLOC, __func__, __LINE__);
        return NULL;
    }
    /*tableinfoを初期化*/
    memset(tableinfo, 0, sizeof(TableInfo));

    /*tableNameという名前のファイルを開く*/
    if((file=openFile(tableFileName)) == NULL){
        printErrorMessage(ERR_MSG_OPEN, __func__, __LINE__);
        free(tableinfo);
        return NULL;
    }
    
    /*それぞれのデータを取り出し、新しく作ったTableInfoに代入する*/
    if(readPage(file, 0, page) == NG){
        printErrorMessage(ERR_MSG_READ, __func__, __LINE__);
        free(tableinfo);
        return NULL;
    }
    
    p = page;

    memcpy(&num, p, sizeof(int));
    p += sizeof(int);
    tableinfo->numField = num;

    for (i = 0; i < num; i++){
        /*i番目の名前の取得*/
        memcpy(name, p, MAX_FIELD_NAME);
        p += MAX_FIELD_NAME;
        strcpy(tableinfo->fieldInfo[i].name, name);

        /*i番目のデータ型の取得*/
        memcpy(&data, p, sizeof(int));
        p += sizeof(int);
        tableinfo->fieldInfo[i].dataType = data;
    }
        

    /*ファイルをクローズする*/
    if(closeFile(file) == NG){
        printErrorMessage(ERR_MSG_CLOSE, __func__, __LINE__);
        free(tableinfo);
        return NULL;
    }

    /*TableInfoを返す*/
    return tableinfo;
}
Exemple #19
0
void MyVorbisExtractor::buildTableOfContents() {
    off64_t offset = mFirstDataOffset;
    Page page;
    ssize_t pageSize;
#ifndef MTK_AOSP_ENHANCEMENT
    while ((pageSize = readPage(offset, &page)) > 0) {
#else
	struct timeval tb,te;
	gettimeofday(&tb,NULL);
    while (mTocStarted && ((pageSize = readPage(offset, &page)) > 0)) {
        if(page.mGranulePosition < 0xFFFFFFFFFFFF)
        {
#endif
        mTableOfContents.push();

        TOCEntry &entry =
            mTableOfContents.editItemAt(mTableOfContents.size() - 1);

        entry.mPageOffset = offset;
        entry.mTimeUs = page.mGranulePosition * 1000000ll / mVi.rate;
#ifdef MTK_AOSP_ENHANCEMENT
        //sleep 100ms for consumes over 2s
        gettimeofday(&te,NULL);
        if((te.tv_sec - tb.tv_sec) > 2)
         {
        	  gettimeofday(&tb,NULL);
	          usleep(100000);	  
         }
        }
#endif
        offset += (size_t)pageSize;
    }

    // Limit the maximum amount of RAM we spend on the table of contents,
    // if necessary thin out the table evenly to trim it down to maximum
    // size.

    static const size_t kMaxTOCSize = 8192;
    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);

    size_t numerator = mTableOfContents.size();

    if (numerator > kMaxNumTOCEntries) {
        size_t denom = numerator - kMaxNumTOCEntries;

        size_t accum = 0;
        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
            accum += denom;
            if (accum >= numerator) {
                mTableOfContents.removeAt(i);
                accum -= numerator;
            }
        }
    }
#ifdef MTK_AOSP_ENHANCEMENT
    mTocDone = true;
#endif
}

status_t MyVorbisExtractor::verifyHeader(
        MediaBuffer *buffer, uint8_t type) {
    const uint8_t *data =
        (const uint8_t *)buffer->data() + buffer->range_offset();

    size_t size = buffer->range_length();

    if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
        return ERROR_MALFORMED;
    }

    ogg_buffer buf;
    buf.data = (uint8_t *)data;
    buf.size = size;
    buf.refcount = 1;
    buf.ptr.owner = NULL;

    ogg_reference ref;
    ref.buffer = &buf;
    ref.begin = 0;
    ref.length = size;
    ref.next = NULL;

    oggpack_buffer bits;
    oggpack_readinit(&bits, &ref);

    CHECK_EQ(oggpack_read(&bits, 8), type);
    for (size_t i = 0; i < 6; ++i) {
        oggpack_read(&bits, 8);  // skip 'vorbis'
    }

    switch (type) {
        case 1:
        {
#ifndef MTK_AOSP_ENHANCEMENT    	
            CHECK_EQ(0, _vorbis_unpack_info(&mVi, &bits));
#else
            _vorbis_unpack_info(&mVi, &bits);//skip the CHECK
#endif
            mMeta->setData(kKeyVorbisInfo, 0, data, size);
            mMeta->setInt32(kKeySampleRate, mVi.rate);
            mMeta->setInt32(kKeyChannelCount, mVi.channels);
            
#ifdef MTK_AOSP_ENHANCEMENT
            if(mVi.channels > 2)
            {
#ifndef MTK_SWIP_VORBIS
                SXLOGE("Tremolo does not support multi channel");
                return ERROR_UNSUPPORTED;
#endif
            }
#endif 

            ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
            ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
            ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
            ALOGV("window-bitrate = %ld", mVi.bitrate_window);

            off64_t size;
            if (mSource->getSize(&size) == OK) {
                uint64_t bps = approxBitrate();
                if (bps != 0) {
                    mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
                }
            }
            break;
        }

        case 3:
        {
            if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
                return ERROR_MALFORMED;
            }

            parseFileMetaData();
            break;
        }

        case 5:
        {
            if (0 != _vorbis_unpack_books(&mVi, &bits)) {
                return ERROR_MALFORMED;
            }

            mMeta->setData(kKeyVorbisBooks, 0, data, size);
            break;
        }
    }

    return OK;
}

uint64_t MyVorbisExtractor::approxBitrate() {
    if (mVi.bitrate_nominal != 0) {
        return mVi.bitrate_nominal;
    }

    return (mVi.bitrate_lower + mVi.bitrate_upper) / 2;
}

void MyVorbisExtractor::parseFileMetaData() {
    mFileMeta = new MetaData;
#ifdef MTK_AOSP_ENHANCEMENT
    if(mFileMeta.get() == NULL)  return;
#endif
    mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);

    for (int i = 0; i < mVc.comments; ++i) {
        const char *comment = mVc.user_comments[i];
        size_t commentLength = mVc.comment_lengths[i];
        parseVorbisComment(mFileMeta, comment, commentLength);
        //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
    }
}
Exemple #20
0
off64_t MyVorbisExtractor::findAccuratePageOffset(uint64_t samples,off64_t ofStart,off64_t ofEnd)
{
	  uint64_t sgranulePosition,egranulePosition,granulePositionGuess;
	  off64_t  offsetGuess;
    
  	findGranulePositionofPage(ofStart, &sgranulePosition); 	  
	  findGranulePositionofPage(ofEnd, &egranulePosition);  	 
	  SXLOGD("ofStart:%lld,sgranulePosition:%lld,ofEnd:%lld,egranulePosition:%lld,samples:%lld",ofStart,sgranulePosition,ofEnd,egranulePosition,samples);
	  if((sgranulePosition == egranulePosition)||(samples <= sgranulePosition))
	  	 return ofStart;
	  if(samples >= egranulePosition)
	  	 return ofEnd;
	  offsetGuess = (ofEnd *(samples - sgranulePosition) + ofStart * (egranulePosition - samples))/(egranulePosition-sgranulePosition);
	  if(findGranulePositionofPage(offsetGuess, &granulePositionGuess) != OK)
	  {
	    SXLOGD("offsetGuess is abnormal,return the start offset");
	    return ofStart;
	  }
	  else
    SXLOGD("offsetGuess:%lld,granulePositionGuess:%lld",offsetGuess,granulePositionGuess); 
	  
	  if(samples >= granulePositionGuess)
	  {
	  	 off64_t pageOffset;
       status_t err = findNextPage_l(offsetGuess, &pageOffset);
       if (err != OK) {
       	  return offsetGuess;
       }
       else
       {
         Page page;
         ssize_t n = readPage(pageOffset, &page);
         if (n <= 0) {
            return offsetGuess;
         }
         offsetGuess = pageOffset;
       }
       if(findGranulePositionofPage(offsetGuess, &granulePositionGuess) != OK)
       {
	       SXLOGD("offsetGuess is abnormal,return the start offset");
	       return ofStart;
	     }
       if(samples <= granulePositionGuess)
	  	    return offsetGuess;
	  	 else 
	  	 	return findAccuratePageOffset(samples,offsetGuess,ofEnd); 		
	   }
    else
    {
    	 off64_t pageOffset;
       status_t err = findNextPage_l(ofStart, &pageOffset);
       if (err != OK) {
       	  return offsetGuess;
       }
       else
       {
         Page page;
         ssize_t n = readPage(pageOffset, &page);
         if (n <= 0) {
            return offsetGuess;
         }
         ofStart = pageOffset;
       }
       findGranulePositionofPage(ofStart, &sgranulePosition);
       if(samples <= sgranulePosition)
	  	    return ofStart;
	  	 else 
	  	 	return findAccuratePageOffset(samples,ofStart,offsetGuess);
     }
}
int main(void)
{
  int ret;
  int fd;
  int tries = 0;
  int tagIdLen = MAX_TAG_ID_LENGTH;
  unsigned char tagId[MAX_TAG_ID_LENGTH];

  bcm2835_init();

  // We're assuming the caller has made sure there's a tag present

  int page = 4; // skip the first four pages as they hold general info on the tag
  int pageLen = MAX_TAG_ID_LENGTH;
  int contentIdx = 0; // where in the content buffer we're up to
  while ((contentIdx < kContentsBufferLen) && readPage(fd, page, &gContentsBuffer[contentIdx], &pageLen))
  {
    contentIdx += pageLen;
    page++; // move onto the next page
  }
#if DEBUG
  printf("Read in %d bytes\n", contentIdx);
  int i;
  for (i = 0; i < contentIdx; i++)
  {
    printf("%02x ", gContentsBuffer[i]);
    if (i % 16 == 15)
    {
      printf("\n");
    }
  }
  printf("\n");
#endif
  // Parse the content to look for NDEF records
  int idx = 0;
  while (idx < contentIdx)
  {
    // Look for the initial TLV structure
    uint8_t t = gContentsBuffer[idx++];
    if (t != 0)
    {
      // It's not a NULL TLV
#if DEBUG
      printf("t: %02x\n", t);
#endif
      int l = gContentsBuffer[idx++];
      idx = MIN(idx, contentIdx);
      if (l == 0xff)
      {
        // 3-byte length format, so the next two bytes are the actual length
        l = gContentsBuffer[idx++] << 8 | gContentsBuffer[idx++];
        idx = MIN(idx, contentIdx);
      }
      uint8_t tnf_byte;
      uint8_t typeLength =0;
      uint32_t payloadLength =0;
      uint8_t idLength =0;
      int messageEnd = idx + l;
      switch (t)
      {
      case 0x03:
        // We've found an NDEF message
        // Parse out each record in it
#if DEBUG
        printf("NDEF message found\n", t);
#endif
        while ((idx < messageEnd) && (idx < contentIdx))
        {
          tnf_byte = gContentsBuffer[idx++];
          idx = MIN(idx, contentIdx);
          typeLength = gContentsBuffer[idx++];
          idx = MIN(idx, contentIdx);
          if (tnf_byte & NDEF_RECORD_SHORT_RECORD)
          {
            payloadLength = gContentsBuffer[idx++];
          }
          else
          {
            payloadLength = (gContentsBuffer[idx++] << 24) |
                            (gContentsBuffer[idx++] << 16) |
                            (gContentsBuffer[idx++] << 8) |
                            (gContentsBuffer[idx++]);
          }
          idx = MIN(idx, contentIdx);
          if (tnf_byte & NDEF_RECORD_ID_LENGTH_PRESENT) {
            idLength = gContentsBuffer[idx++];
            idx = MIN(idx, contentIdx);
          }

#if DEBUG
          printf("NDEF record: tnf_byte: 0x%02x, typeLength: %d, idLength: %d, payloadLength: %d, next byte: 0x%02x\n", tnf_byte, typeLength, idLength, payloadLength, gContentsBuffer[idx]);
#endif
          // Let's see if it's a record we're interested in...
          if ( ((tnf_byte & NDEF_RECORD_TNF_MASK) == NDEF_TNF_NFC_WELL_KNOWN) && 
              (typeLength == 1) && (gContentsBuffer[idx] == NDEF_RTD_TEXT) )
          {
            // It's text!  Let's output it...
            idx += typeLength; // skip over the type
            // skip the language
            int langLength = gContentsBuffer[idx++];
            payloadLength--; // for the langLength byte
            payloadLength -= langLength;
            idx += langLength;
            while (payloadLength-- > 0)
            {
              idx = MIN(idx, contentIdx);
              printf("%c", gContentsBuffer[idx++]);
            }
            // ...and quit
            exit(0);
          }
          else
          {
            // Skip this message
#if DEBUG
            printf("Skipping (tnf_byte: %02x)\n", tnf_byte);
            printf("idx: %d messageEnd: %d typeLength: %d idLength: %d payloadLength: %d contentIdx: %d\n", idx, messageEnd, typeLength, idLength, payloadLength, contentIdx);
#endif
            idx += typeLength+idLength+payloadLength;
            idx = MIN(idx, contentIdx);
          }

          if (tnf_byte & NDEF_RECORD_MESSAGE_END)
          {
            break;
          }
        }
        break;
      case 0xfe:
        // Terminator TLV block, give up now
        exit(1);
        break;
      default:
        // Skip to the next TLV
        idx += l;
        break;
      };
    }
  }
}   
Exemple #22
0
void readChip(int totMem, unsigned char *buffer) {
	int paginas = totMem / 256, pag;
	
	for(pag=0; pag<paginas; pag++)
		readPage(pag, &buffer[pag * 256]);
}
Exemple #23
0
int main(int argc, const char **argv)
{

	MemServerRequestProxy *hostMemServerRequest = new MemServerRequestProxy(IfcNames_HostMemServerRequest);
	MMURequestProxy *dmap = new MMURequestProxy(IfcNames_HostMMURequest);
	DmaManager *dma = new DmaManager(dmap);
	MemServerIndication *hostMemServerIndication = new MemServerIndication(hostMemServerRequest, IfcNames_HostMemServerIndication);
	MMUIndication *hostMMUIndication = new MMUIndication(dma, IfcNames_HostMMUIndication);

	fprintf(stderr, "Main::allocating memory...\n");

	device = new FlashRequestProxy(IfcNames_FlashRequest);
	FlashIndication *deviceIndication = new FlashIndication(IfcNames_FlashIndication);
	
	srcAlloc = portalAlloc(srcAlloc_sz);
	dstAlloc = portalAlloc(dstAlloc_sz);
	srcBuffer = (unsigned int *)portalMmap(srcAlloc, srcAlloc_sz);
	dstBuffer = (unsigned int *)portalMmap(dstAlloc, dstAlloc_sz);

	fprintf(stderr, "dstAlloc = %x\n", dstAlloc); 
	fprintf(stderr, "srcAlloc = %x\n", srcAlloc); 
	
	pthread_mutex_init(&flashReqMutex, NULL);
	pthread_cond_init(&flashFreeTagCond, NULL);

	printf( "Done initializing hw interfaces\n" ); fflush(stdout);

	portalExec_start();
	printf( "Done portalExec_start\n" ); fflush(stdout);

	portalDCacheFlushInval(dstAlloc, dstAlloc_sz, dstBuffer);
	portalDCacheFlushInval(srcAlloc, srcAlloc_sz, srcBuffer);
	ref_dstAlloc = dma->reference(dstAlloc);
	ref_srcAlloc = dma->reference(srcAlloc);

	for (int t = 0; t < NUM_TAGS; t++) {
		readTagTable[t].busy = false;
		writeTagTable[t].busy = false;
		int byteOffset = t * PAGE_SIZE;
		device->addDmaWriteRefs(ref_dstAlloc, byteOffset, t);
		device->addDmaReadRefs(ref_srcAlloc, byteOffset, t);
		readBuffers[t] = dstBuffer + byteOffset/sizeof(unsigned int);
		writeBuffers[t] = srcBuffer + byteOffset/sizeof(unsigned int);
	}
	
	for (int blk=0; blk<BLOCKS_PER_CHIP; blk++) {
		for (int c=0; c<CHIPS_PER_BUS; c++) {
			for (int bus=0; bus< CHIPS_PER_BUS; bus++) {
				flashStatus[bus][c][blk] = UNINIT;
			}
		}
	}


	for (int t = 0; t < NUM_TAGS; t++) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			readBuffers[t][i] = 0;
			writeBuffers[t][i] = 0;
		}
	}

	device->start(0);
	device->setDebugVals(0,0); //flag, delay

	device->debugDumpReq(0);
	sleep(1);
	device->debugDumpReq(0);
	sleep(1);
	//TODO: test writes and erases
	

	
	//test erases
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				eraseBlock(bus, chip, blk, waitIdleEraseTag());
			}
		}
	}

	while (true) {
		usleep(100);
		if ( getNumErasesInFlight() == 0 ) break;
	}
	
	
	//read back erased pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				readPage(bus, chip, blk, page, waitIdleReadBuffer());
			}
		}
	}
	while (true) {
		usleep(100);
		if ( getNumReadsInFlight() == 0 ) break;
	}


	//write pages
	//FIXME: in old xbsv, simulatneous DMA reads using multiple readers cause kernel panic
	//Issue each bus separately for now
	for (int bus = 0; bus < NUM_BUSES; bus++){
	
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				int page = 0;
				//get free tag
				int freeTag = waitIdleWriteBuffer();
				//fill write memory
				for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) {
					writeBuffers[freeTag][w] = hashAddrToData(bus, chip, blk, w);
				}
				//send request
				writePage(bus, chip, blk, page, freeTag);
			}
			while (true) {
				usleep(100);
				if ( getNumWritesInFlight() == 0 ) break;
			}
		}
		
		
	} //each bus
	

	timespec start, now;
	clock_gettime(CLOCK_REALTIME, & start);

	for (int repeat = 0; repeat < 1; repeat++){
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				for (int bus = 0; bus < NUM_BUSES; bus++){

				//int blk = rand() % 1024;
				//int chip = rand() % 8;
				//int bus = rand() % 8;
					int page = 0;
					readPage(bus, chip, blk, page, waitIdleReadBuffer());
				}
			}
		}
	}
	
	int elapsed = 0;
	while (true) {
		usleep(100);
		if (elapsed == 0) {
			elapsed=10000;
			device->debugDumpReq(0);
		}
		else {
			elapsed--;
		}
		if ( getNumReadsInFlight() == 0 ) break;
	}
	device->debugDumpReq(0);

	clock_gettime(CLOCK_REALTIME, & now);
	fprintf(stderr, "LOG: finished reading from page! %f\n", timespec_diff_sec(start, now) );

	for ( int t = 0; t < NUM_TAGS; t++ ) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			fprintf(stderr,  "%x %x %x\n", t, i, readBuffers[t][i] );
		}
	}
	if (testPass==1) {
		fprintf(stderr, "LOG: TEST PASSED!\n");
	}
	else {
		fprintf(stderr, "LOG: **ERROR: TEST FAILED!\n");
	}


}
Exemple #24
0
void crawler::loadPage(std::string url) {
    std::string content;


    boost::match_results<std::string::const_iterator> res;
    boost::regex_search(url, res, baseUrlPattern);
    std::string baseUrl = res[1];

    visitedLock.lock();
    std::cout << lineOverride << pageQueue.size() << "  " << connErrors << "e  " << dict.size() << "w  " << pageQueue.size() / (float) pageCounter << std::flush;
#ifdef BASE_MAX
    int count = visited.count(baseUrl);
    if (count >= BASE_MAX) {
#else
    int count = visited.count(url);
    if (count) {
#endif
        visitedLock.unlock();
        return;
    }
    visitedLock.unlock();

    if (!readPage(url, content))
        return;

    addContentToQueue(url, content);
}

void crawler::analyzePage(std::string url, std::string content) {
    if (!boost::regex_match(content, doctypePattern))
        return;

    boost::match_results<std::string::const_iterator> res;
    boost::regex_search(url, res, urlPattern);
    std::string baseUrl = res[3];
    std::string folderUrl = res[2];
    std::string fileUrl = res[1];

    visitedLock.lock();
#ifdef BASE_MAX
    int count = visited.count(baseUrl);
    if (count >= BASE_MAX) {
#else
    int count = visited.count(url);
    if (count) {
#endif
        visitedLock.unlock();
        return;
    } else if (!count) {
#ifdef USE_BASE
        std::cout << lineOverride << ++pageCounter << "   " << baseUrl << "   " << std::endl;
#else
        std::cout << lineOverride << ++pageCounter << "   " << url << "   " << std::endl;
#endif
    }

#ifdef BASE_MAX
    visited.insert(baseUrl);
#else
    visited.insert(url);
#endif

    visitedLock.unlock();

    boost::sregex_iterator hrefIt(content.begin(), content.end(), linkPattern);

    std::for_each(hrefIt, boost::sregex_iterator(), [this, baseUrl, fileUrl, folderUrl](const boost::match_results<std::string::const_iterator>& what) {
        std::string link = what[1];

        if (boost::regex_match(link, javascriptPattern)) {
            return;
        }

        if (link.substr(0, 1) == ".") {
            link = "/" + link;
        }

        if (link.substr(0, 7) == "http://" || link.substr(0, 8) == "https://") {
        } else if (link.substr(0, 2) == "//") {
            link = "http:" + link;
        } else if (link.substr(0, 1) == "/") {
            link = baseUrl + link;
        } else if (link.substr(0, 1) == "?") {
            link = fileUrl + link;
        } else {
            link = folderUrl + link;
        }


        if (boost::regex_match(link, ignoreTypePattern)) {
            return;
        }


        boost::match_results<std::string::const_iterator> res;

#ifdef REQUIRE_TLD
                boost::regex_search(link, res, tldPattern);
        if (res[1] != REQUIRE_TLD) {
            return;
        }
#endif

#ifdef REQUIRE_URL
    	boost::regex_search(link, res, baseUrlPattern);
    	if(res[1] != REQUIRE_URL) {
            return;
        }
#endif


        boost::regex_search(link, res, baseUrlPattern);
                std::string baseLink = res[1];

                visitedLock.lock();
#ifdef BASE_MAX
                if (visited.count(baseLink) < BASE_MAX) {
#else
                if (!visited.count(link)) {
#endif
#ifdef USE_BASE
            addPageToQueue(baseLink);
#else
            addPageToQueue(link);
#endif
        }
        visitedLock.unlock();
    });


    content = boost::regex_replace(content, ignoreTagsPattern, " ", boost::match_default | boost::format_all);
    content = boost::regex_replace(content, tagPattern, " ", boost::match_default | boost::format_all);

    boost::sregex_token_iterator wordIt(content.begin(), content.end(), wordPattern, 0), wordItEnd;
    dictLock.lock();
    while (wordIt != wordItEnd) {
        std::string word = *wordIt++;

        auto it = dict.find(word);
        if (it == dict.end()) {
            dict.insert(std::make_pair(word, 1));
        } else {
            it->second++;
        }
    }
    dictLock.unlock();
}

bool crawler::readPage(std::string &url, std::string &pageData) {
    try {
        curlpp::Easy myRequest;

        myRequest.setOpt<curlpp::options::WriteFunction>(
                [&pageData](char* buf, size_t size, size_t nmemb) {
                    for (int c = 0; c < size * nmemb; c++) {
                        pageData.push_back(buf[c]);
                    }
                    return size*nmemb;
                });
        myRequest.setOpt<curlpp::options::FollowLocation>(1);
        myRequest.setOpt<curlpp::options::Url>(url);
        myRequest.setOpt<curlpp::options::Timeout>(TIMEOUT);

        myRequest.perform();

        url = curlpp::infos::EffectiveUrl().get(myRequest);
    } catch (curlpp::RuntimeError & e) {
        connErrors++;
        return false;
    } catch (curlpp::LogicError & e) {
        connErrors++;
        return false;
    }

    return true;
}
Exemple #25
0
int FileSystem::readPage(fs_pageno pageNumber, void *buffer) {
	return readPage(pageNumber, 0, pageSize, buffer);
}
//Leo una pagina y luego la muevo a la posicion deseada
void copyPage(int from, int to) {

	char *page = readPage(from);
	writePage(to, page);

}
Exemple #27
0
//---------------------------------------------
//Local erase, read, write, read test
//---------------------------------------------
void local_test(bool check, int read_repeat, int debug_lvl ) {
	LOG(0, "LOG: starting local_test...\n");
	g_checkdata = check;
	g_debuglevel = debug_lvl;
	g_testpass = true;
	int node = myid;

	timespec start, now;
	double timeElapsed = 0; 
	double bw = 0;
	//erase all blocks
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				eraseBlock(node, bus, chip, blk, waitIdleEraseTag());
			}
		}
	}

	while (true) {
		if ( getNumErasesInFlight() == 0 ) break;
	}

	//read back erased pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
			}
		}
	}

	while (true) {
		if ( getNumReadsInFlight() == 0 ) break;
	}


	int pagesWritten = 0;
	clock_gettime(CLOCK_REALTIME, & start);
	//write pages
	for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
		for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
			for (int bus = 0; bus < NUM_BUSES; bus++){
				int page = 0;
				int freeTag = waitIdleWriteBuffer();
				if (g_checkdata) {
					//fill write memory only if we're doing readback checks
					for (int w=0; w<PAGE_SIZE/sizeof(unsigned int); w++) {
						writeBuffers[freeTag][w] = hashAddrToData(node, bus, chip, blk, w);
					}
				}
				//send request
				writePage(node, bus, chip, blk, page, freeTag); 
				pagesWritten++;
			}
		}
	}
	while (true) {
		if ( getNumWritesInFlight() == 0 ) break;
	}
	clock_gettime(CLOCK_REALTIME, & now);
	timeElapsed = timespec_diff_sec(start, now);
	bw = (pagesWritten*8)/timeElapsed/1024; //MB/s
	//double latency = timeElapsed/pagesWritten;
	//double latency_us = latency*1000000;
	LOG(0, "LOG: finished writing to page. Time=%f, NumPages=%d, BW=%f MB/s\n", 
							timeElapsed, pagesWritten, bw);


	int pagesRead = 0;
	clock_gettime(CLOCK_REALTIME, & start);
	for (int rep = 0; rep < read_repeat; rep++) {
		for (int blk = 0; blk < BLOCKS_PER_CHIP; blk++){
			for (int chip = 0; chip < CHIPS_PER_BUS; chip++){
				for (int bus = 0; bus < NUM_BUSES; bus++){
					int page = 0;
					readPage(node, bus, chip, blk, page, waitIdleReadBuffer());
					pagesRead++;
				}
			}
		}
	}
	while (true) {
		if ( getNumReadsInFlight() == 0 ) break;
	}
	clock_gettime(CLOCK_REALTIME, & now);
	timeElapsed = timespec_diff_sec(start, now);
	bw = (pagesRead*8)/timeElapsed/1024; //MB/s

	LOG(0, "LOG: reading from page. Time=%f, NumPages=%d, BW=%f MB/s\n", 
							timeElapsed, pagesRead, bw);

	device->debugDumpReq(0);
	sleep(1);

	for ( int t = 0; t < NUM_TAGS; t++ ) {
		for ( int i = 0; i < PAGE_SIZE/sizeof(unsigned int); i++ ) {
			LOG(1, "%x %x %x\n", t, i, readBuffers[t][i] );
		}
	}

	if (g_checkdata) {
		if (g_testpass) {
			LOG(0, "LOG: local_test passed!\n");
		}
		else {
			LOG(0, "LOG: **ERROR: local_test FAILED!\n");
		}
	} else {
			LOG(0, "LOG: local_test complete. No checks done\n");
	}
}
Exemple #28
0
int FileSystem::defrag() {
	printf("defrag called\n");
	exit(1);
	int32_t nextFreePage = 1;
	int32_t *newPosition = (int32_t*)malloc(pageCount * sizeof(int32_t));
	// page 0 must not be moved around
	newPosition[0] = 0;
	for (int i = 1; i < pageCount; i++)
		newPosition[i] = -1;

	// first, perform a DFS to assign new page positions
	int upperFileLimit = doubleIntsPerPage * fileMappingSize;
	for (int file = 0; file < upperFileLimit; file++) {
		int32_t page = getFirstPage(file);
		while (page > 0) {
			assert(newPosition[page] < 0);
			newPosition[page] = nextFreePage++;
			page = getPageStatus(page);
		}
	} // end for (int file = 0; file < upperFileLimit; file++)

	// then, assign new page numbers to the remaining (free) pages
	for (int i = 1; i < pageCount; i++)
		if (getPageStatus(i) == UNUSED_PAGE)
			newPosition[i] = nextFreePage++;

	// make sure that every page has been assigned a new location
	assert(nextFreePage == pageCount);

	// correct data in the page layout table
	int32_t *oldPageLayout = (int32_t*)malloc(pageLayoutSize * intsPerPage * sizeof(int32_t));
	int32_t *newPageLayout = (int32_t*)malloc(pageLayoutSize * intsPerPage * sizeof(int32_t));
	for (int i = 0; i < pageLayoutSize; i++)
		readPage(pageCount + i, &oldPageLayout[intsPerPage * i]);
	for (int page = 0; page < pageCount; page++) {
		if (oldPageLayout[page] <= 0)
			newPageLayout[newPosition[page]] = oldPageLayout[page];
		else
			newPageLayout[newPosition[page]] = newPosition[oldPageLayout[page]];
	}
	for (int i = 0; i < pageLayoutSize; i++)
		writePage(pageCount + i, &newPageLayout[intsPerPage * i]);	
	free(newPageLayout);
	free(oldPageLayout);

	// correct page numbers in the file->page table
	for (int file = 0; file < upperFileLimit; file++) {
		int32_t page = getFirstPage(file);
		if (page >= 0)
			setFirstPage(file, newPosition[page]);
	} // end for (int file = 0; file < upperFileLimit; file++)

	byte *buffer1 = (byte*)malloc(pageSize);
	byte *buffer2 = (byte*)malloc(pageSize);
	// happy reading/writing while moving all pages to their new positions
	for (int page = 0; page < pageCount; page++) {
		int currentPage = page;
		while (newPosition[currentPage] != currentPage) {
			assert(newPosition[currentPage] >= page);
			int32_t newPos = newPosition[currentPage];

			// swap data in pages "currentPage" and "newPos"
			if (readPage(currentPage, buffer1) == FILESYSTEM_ERROR)
				return FILESYSTEM_ERROR;
			if (readPage(newPos, buffer2) == FILESYSTEM_ERROR)
				return FILESYSTEM_ERROR;
			if (writePage(newPos, buffer1) == FILESYSTEM_ERROR)
				return FILESYSTEM_ERROR;
			if (writePage(currentPage, buffer2) == FILESYSTEM_ERROR)
				return FILESYSTEM_ERROR;

			// update permutation table
			newPosition[currentPage] = newPosition[newPos];
			newPosition[newPos] = newPos;
		}
	} // end for (int page = 0; page < pageCount; page++)
	free(buffer2);
	free(buffer1);

	free(newPosition);
	return FILESYSTEM_SUCCESS;
} // end of defrag()
Exemple #29
0
int FileSystem::changeSize(fs_pageno newPageCount) {
	bool mustReleaseLock = getLock();
	int result = FILESYSTEM_ERROR;

	// if "newPageCount" is too small, an error is returned
	if ((newPageCount < MIN_PAGE_COUNT) || (newPageCount < getUsedPageCount()) ||
			(newPageCount > MAX_PAGE_COUNT))
		goto endOfChangeSize;

	if (newPageCount < pageCount) {
		// First, defragment the filesystem in order to be able to reduce the size.
		if (defrag() == FILESYSTEM_ERROR)
			goto endOfChangeSize;

		// Then, decrease the size of the filesystem.
		int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage;

		byte *pageBuffer = (byte*)malloc(pageSize);
		
		// copy page layout data to new position
		for (int i = 0; i < newPageLayoutSize; i++) {
			readPage(pageCount + i, pageBuffer);
			writePage(newPageCount + i, pageBuffer);
		}
		
		// copy file->page mappings to new position
		for (int i = 0; i < fileMappingSize; i++) {
			readPage(pageCount + pageLayoutSize + i, pageBuffer);
			writePage(newPageCount + newPageLayoutSize + i, pageBuffer);
		}

		free(pageBuffer);

		pageCount = newPageCount;
		pageLayoutSize = newPageLayoutSize;

		// write changed preamble to disk
		int32_t pageCountOnDisk = (int32_t)pageCount;
		int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize;
		lseek(dataFile, 2 * INT_SIZE, SEEK_SET);
		forced_write(dataFile, &pageCountOnDisk, INT_SIZE);
		forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE);

		// change the size of the data file
		off_t fileSize = pageSize;
		fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize);
		forced_ftruncate(dataFile, fileSize);
	} // end if (newPageCount < pageCount)

	if (newPageCount > pageCount) {
		// change the size of the data file
		int newPageLayoutSize = (newPageCount + (intsPerPage - 1)) / intsPerPage;
		off_t fileSize = pageSize;
		fileSize *= (newPageCount + newPageLayoutSize + fileMappingSize);
		if (ftruncate(dataFile, fileSize) < 0) {
			fprintf(stderr, "Filesystem size could not be changed.\n");
			perror(NULL);
			goto endOfChangeSize;
		}
		if (getSize() != fileSize) {
			fprintf(stderr, "Filesystem size could not be changed.\n");
			perror(NULL);
			goto endOfChangeSize;
		}

		int oldPageCount = pageCount;
		pageCount = newPageCount;
		int oldPageLayoutSize = pageLayoutSize;
		pageLayoutSize = newPageLayoutSize;

		// write changed preamble to disk
		int32_t pageCountOnDisk = (int32_t)pageCount;
		int32_t pageLayoutSizeOnDisk = (int32_t)pageLayoutSize;
		lseek(dataFile, 2 * INT_SIZE, SEEK_SET);
		forced_write(dataFile, &pageCountOnDisk, INT_SIZE);
		forced_write(dataFile, &pageLayoutSizeOnDisk, INT_SIZE);

		byte *pageBuffer = (byte*)malloc(pageSize);

		// copy file->page mappings to new position
		for (int i = fileMappingSize - 1; i >= 0; i--) {
			readPage(oldPageCount + oldPageLayoutSize + i, pageBuffer);
			writePage(newPageCount + newPageLayoutSize + i, pageBuffer);
		}

		// copy page layout data to new position
		for (int i = oldPageLayoutSize - 1; i >= 0; i--) {
			readPage(oldPageCount + i, pageBuffer);
			writePage(newPageCount + i, pageBuffer);
		}
		// initialize layout data for the new pages
		int32_t unusedValue = UNUSED_PAGE;
		for (int i = 0; i < intsPerPage; i++)
			memcpy(&pageBuffer[i * INT_SIZE], &unusedValue, INT_SIZE);
		for (int i = oldPageLayoutSize; i < newPageLayoutSize; i++)
			 writePage(newPageCount + i, pageBuffer);

		free(pageBuffer);
		
		// update the freePages and freeFileNumbers arrays
		free(freePages); freePages = NULL;
		free(freeFileNumbers); freeFileNumbers = NULL;
		initializeFreeSpaceArrays();
	} // end if (newPageCount > pageCount)

	enableCaching();
	result = FILESYSTEM_SUCCESS;

endOfChangeSize:
	if (mustReleaseLock)
		releaseLock();
	return result;
} // end of changeSize(fs_pageno)
Exemple #30
0
fs_pageno FileSystem::claimFreePage(fs_fileno owner, fs_pageno closeTo) {
	bool mustReleaseLock = getLock();
	int result = FILESYSTEM_ERROR;

	fs_pageno oldPageCount, newPageCount;

	int origCloseTo = closeTo;
	if ((closeTo < 0) || (closeTo >= pageCount)) {
		origCloseTo = 0;
		closeTo = 0;
	}
	else
		closeTo = closeTo / intsPerPage;

	// buffer for speeding up the individual status requests
	int32_t *data = (int32_t*)malloc((intsPerPage + 1) * sizeof(int32_t));
	
	if (freePages[closeTo] > 0) {
		if (readPage(pageCount + closeTo, data) == FILESYSTEM_ERROR) {
			free(data);
			goto endOfClaimFreePage;
		}
		for (int j = origCloseTo % intsPerPage; j < intsPerPage; j++)
			if (data[j] == UNUSED_PAGE) {
				free(data);
				result = closeTo * intsPerPage + j;
				goto endOfClaimFreePage;
			}
		for (int j = origCloseTo % intsPerPage; j >= 0; j--)
			if (data[j] == UNUSED_PAGE) {
				free(data);
				result = closeTo * intsPerPage + j;
				goto endOfClaimFreePage;
			}
	} // end if (freePages[closeTo] > 0)

	// if nothing close to "closeTo" can be found, just search everywhere
	for (int j = closeTo + 1; j < pageLayoutSize; j++) {
		if (freePages[j] > 0) {
			if (readPage(pageCount + j, data) == FILESYSTEM_ERROR) {
				free(data);
				goto endOfClaimFreePage;
			}
			for (int k = 0; k < intsPerPage; k++) {
				if (data[k] == UNUSED_PAGE) {
					free(data);
					result = j * intsPerPage + k;
					goto endOfClaimFreePage;
				}
			}
		}
	}
	for (int j = closeTo - 1; j >= 0; j--) {
		if (freePages[j] > 0) {
			if (readPage(pageCount + j, data) == FILESYSTEM_ERROR) {
				free(data);
				goto endOfClaimFreePage;
			}
			for (int k = 0; k < intsPerPage; k++) {
				if (data[k] == UNUSED_PAGE) {
					free(data);
					result = j * intsPerPage + k;
					goto endOfClaimFreePage;
				}
			}
		}
	}

	free(data);

	// If we come here, then no free page has been found. If pageCount has reached
	// its maximum value, return an error code.
	assert(pageCount < MAX_PAGE_COUNT);

	// Increase the size of the filesystem.
	oldPageCount = pageCount;
	if (pageCount <= SMALL_FILESYSTEM_THRESHOLD)
		newPageCount = (fs_pageno)(1.41 * 1.41 * oldPageCount);
	else
		newPageCount = (fs_pageno)(1.41 * oldPageCount);
	// obey some constraints on the number of pages in the system
	while (newPageCount % (pageSize / INT_SIZE) != 0)
		newPageCount++;
	if (newPageCount > MAX_PAGE_COUNT)
		newPageCount = MAX_PAGE_COUNT;
	if (changeSize(newPageCount) < 0)
		goto endOfClaimFreePage;
	
	result = claimFreePage(owner, oldPageCount);

endOfClaimFreePage:
	if (mustReleaseLock)
		releaseLock();

	return result;
} // end of claimFreePage(...)