GiSTpage GiSTfile::Allocate() { GiSTpage page; char *buf; if (!IsOpen()) return (0); // See if there's a deleted page buf = new char[PageSize()]; Read(0, buf); memcpy(&page, buf+sizeof(magic), sizeof(GiSTpage)); if (page) { // Reclaim this page Read(page, buf); Write(0, buf); } else { page = lseek(fileHandle, 0, SEEK_END) / PageSize(); memset(buf, 0, PageSize()); write(fileHandle, buf, PageSize()); } delete buf; return page; }
void GiSTfile::CreateNew(const char *filename, bool fTruncateExisting) { if (IsOpen()) return; if (!fTruncateExisting) { fileHandle = open(filename, O_RDWR | O_BINARY); if (fileHandle >= 0) { close(fileHandle); return; } } fileHandle = open(filename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); if (fileHandle < 0) return; SetOpen(1); /* Reserve page 0 */ char *page = new char[PageSize()]; memset(page, 0, PageSize()); memcpy(page, magic, sizeof magic); write(fileHandle, page, PageSize()); delete page; }
void GiSTfile::Read(GiSTpage page, char *buf) { if(IsOpen()) { lseek(fileHandle, page*PageSize(), SEEK_SET); read(fileHandle, buf, PageSize()); } }
void GiSTfile::Write(GiSTpage page, const char *buf) { if(IsOpen()) { lseek(fileHandle, page*PageSize(), SEEK_SET); write(fileHandle, buf, PageSize()); } }
static uintptr_t ReservePoisonArea() { if (sizeof(uintptr_t) == 8) { // Use the hardware-inaccessible region. // We have to avoid 64-bit constants and shifts by 32 bits, since this // code is compiled in 32-bit mode, although it is never executed there. uintptr_t result = (((uintptr_t(0x7FFFFFFFu) << 31) << 1 | uintptr_t(0xF0DEAFFFu)) & ~uintptr_t(PageSize()-1)); printf("INFO | poison area assumed at 0x%.*" PRIxPTR "\n", SIZxPTR, result); return result; } // First see if we can allocate the preferred poison address from the OS. uintptr_t candidate = (0xF0DEAFFF & ~(PageSize() - 1)); void* result = ReserveRegion(candidate, false); if (result == reinterpret_cast<void*>(candidate)) { // success - inaccessible page allocated printf("INFO | poison area allocated at 0x%.*" PRIxPTR " (preferred addr)\n", SIZxPTR, reinterpret_cast<uintptr_t>(result)); return candidate; } // That didn't work, so see if the preferred address is within a range // of permanently inacessible memory. if (ProbeRegion(candidate)) { // success - selected page cannot be usable memory if (result != MAP_FAILED) { ReleaseRegion(result); } printf("INFO | poison area assumed at 0x%.*" PRIxPTR " (preferred addr)\n", SIZxPTR, candidate); return candidate; } // The preferred address is already in use. Did the OS give us a // consolation prize? if (result != MAP_FAILED) { uintptr_t ures = reinterpret_cast<uintptr_t>(result); printf("INFO | poison area allocated at 0x%.*" PRIxPTR " (consolation prize)\n", SIZxPTR, ures); return ures; } // It didn't, so try to allocate again, without any constraint on // the address. result = ReserveRegion(0, false); if (result != MAP_FAILED) { uintptr_t ures = reinterpret_cast<uintptr_t>(result); printf("INFO | poison area allocated at 0x%.*" PRIxPTR " (fallback)\n", SIZxPTR, ures); return ures; } printf("ERROR | no usable poison area found\n"); return 0; }
void WriteFlash(u16 addr, const u8 *buf, int length) { Assert(addr + length <= FlashSize()); Assert(length >= 0); if (length == 0) return; DwGetRegs(0, R, 2); // Cache R0 and R1 int pageOffsetMask = PageSize()-1; int pageBaseMask = ~ pageOffsetMask; if (addr & pageOffsetMask) { // buf starts in the middle of a page int partBase = addr & pageBaseMask; int partOffset = addr & pageOffsetMask; int partLength = min(PageSize()-partOffset, length); DwReadFlash(partBase, PageSize(), pageBuffer); memcpy(pageBuffer+partOffset, buf, partLength); WriteFlashPage(partBase, pageBuffer); addr += partLength; buf += partLength; length -= partLength; } Assert(length == 0 || ((addr & pageOffsetMask) == 0)); // Write whole pages while (length >= PageSize()) { WriteFlashPage(addr, buf); addr += PageSize(); buf += PageSize(); length -= PageSize(); } // Write any remaining partial page if (length) { Assert(length > 0); Assert(length < PageSize()); Assert((addr & pageOffsetMask) == 0); DwReadFlash(addr, PageSize(), pageBuffer); memcpy(pageBuffer, buf, length); WriteFlashPage(addr, pageBuffer); } Ws(" \r"); // Restore cached registers R0 and R1 DwSetRegs(0, R, 2); }
/** Write data to the media through the directory cache. @param aPos linear media position to start writing with @param aDes data to write */ void CMediaWTCache::WriteL(TInt64 aPos,const TDesC8& aDes) { #ifdef _DEBUG if(iCacheDisabled) {//-- cache is disabled for debug purposes User::LeaveIfError(iDrive.WriteCritical(aPos,aDes)); return; } #endif //_DEBUG TUint32 dataLen = aDes.Size(); const TUint8* pData = aDes.Ptr(); const TUint32 PageSz = PageSize(); //-- cache page size //-- find out if aPos is in cache. If not, find a spare page and read data there TInt nPage = FindOrGrabReadPageL(aPos); CWTCachePage* pPage = iPages[nPage]; const TUint32 bytesToPageEnd = (TUint32)(pPage->iStartPos+PageSize() - aPos); //-- number of bytes from aPos to the end of the page // __PRINT5(_L("CMediaWTCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pPage->iStartPos, PageSz, bytesToPageEnd); if(dataLen <= bytesToPageEnd) {//-- data section completely fits to the cache page Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen); //-- update cache //-- make small write a multiple of a write granularity size (if it is used at all) //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal TPtrC8 desBlock(aDes); if(iWrGranularityLog2) {//-- write granularity is used const TInt64 newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the write granularity size TUint32 newLen = (TUint32)(aPos - newPos)+dataLen; //-- round block size up to the write granularity size newLen = RoundUp(newLen, iWrGranularityLog2); const TUint8* pd = pPage->PtrInCachePage(newPos); desBlock.Set(pd, newLen); aPos = newPos; } //-- write data to the media const TInt nErr = iDrive.WriteCritical(aPos, desBlock); if(nErr != KErrNone) {//-- some serious problem occured during writing, invalidate cache. InvalidateCache(); User::Leave(nErr); } }
// Public Methods ////////////////////////////////////////////////////////////// void DataFlash_APM2::Init(void) { pinMode(DF_DATAOUT, OUTPUT); pinMode(DF_DATAIN, INPUT); pinMode(DF_SLAVESELECT,OUTPUT); pinMode(DF_RESET,OUTPUT); pinMode(DF_CARDDETECT, INPUT); // Reset the chip digitalWrite(DF_RESET,LOW); delay(1); digitalWrite(DF_RESET,HIGH); CS_inactive(); //disable device // Setup Serial Port3 in SPI mode (MSPI), Mode 0, Clock: 8Mhz UBRR3 = 0; DDRJ |= (1<<PJ2); // SPI clock XCK3 (PJ2) as output. This enable SPI Master mode // Set MSPI mode of operation and SPI data mode 0. UCSR3C = (1<<UMSEL31)|(1<<UMSEL30); //|(1<<1)|(1<<UCPOL3); // Enable receiver and transmitter. UCSR3B = (1<<RXEN3)|(1<<TXEN3); // Set Baud rate UBRR3 = 0; // SPI running at 8Mhz // get page size: 512 or 528 (by default: 528) df_PageSize=PageSize(); // the last page is reserved for config information df_NumPages = DF_LAST_PAGE - 1; }
// Public Methods ////////////////////////////////////////////////////////////// void DataFlash_APM1::Init(void) { // init to zero df_NumPages = 0; hal.gpio->pinMode(DF_RESET,GPIO_OUTPUT); // Reset the chip hal.gpio->write(DF_RESET,0); hal.scheduler->delay(1); hal.gpio->write(DF_RESET,1); _spi = hal.spi->device(AP_HAL::SPIDevice_Dataflash); if (_spi == NULL) { hal.scheduler->panic( PSTR("PANIC: DataFlash SPIDeviceDriver not found")); return; /* never reached */ } _spi_sem = _spi->get_semaphore(); if (_spi_sem == NULL) { hal.scheduler->panic( PSTR("PANIC: DataFlash SPIDeviceDriver semaphore is null")); return; /* never reached */ } // get page size: 512 or 528 (by default: 528) df_PageSize = PageSize(); // the last page is reserved for config information df_NumPages = DF_LAST_PAGE - 1; }
/* The "negative control" area confirms that our probe logic does detect a * page that is readable, writable, or executable. */ static uintptr_t ReserveNegativeControl() { void* result = ReserveRegion(0, true); if (result == MAP_FAILED) { printf("ERROR | allocating negative control | %s\n", LastErrMsg()); return 0; } // Fill the page with return instructions. RETURN_INSTR_TYPE* p = reinterpret_cast<RETURN_INSTR_TYPE*>(result); RETURN_INSTR_TYPE* limit = reinterpret_cast<RETURN_INSTR_TYPE*>( reinterpret_cast<char*>(result) + PageSize()); while (p < limit) { *p++ = RETURN_INSTR; } // Now mark it executable as well as readable and writable. // (mmap(PROT_EXEC) may fail when applied to anonymous memory.) if (MakeRegionExecutable(result)) { printf("ERROR | making negative control executable | %s\n", LastErrMsg()); return 0; } printf("INFO | negative control allocated at 0x%.*" PRIxPTR "\n", SIZxPTR, (uintptr_t)result); return (uintptr_t)result; }
// Public Methods ////////////////////////////////////////////////////////////// void DataFlash_APM1::Init(void) { pinMode(DF_DATAOUT, OUTPUT); pinMode(DF_DATAIN, INPUT); pinMode(DF_SPICLOCK,OUTPUT); pinMode(DF_SLAVESELECT,OUTPUT); #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) pinMode(DF_RESET,OUTPUT); // Reset the chip digitalWrite(DF_RESET,LOW); delay(1); digitalWrite(DF_RESET,HIGH); #endif df_Read_END=false; dataflash_CS_inactive(); //disable device // Setup SPI Master, Mode 3, fosc/4 = 4MHz SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE3); SPI.setClockDivider(SPI_CLOCK_DIV2); // get page size: 512 or 528 df_PageSize=PageSize(); }
static void* ReserveRegion(uintptr_t aRequest, bool aAccessible) { return mmap(reinterpret_cast<void*>(aRequest), PageSize(), aAccessible ? PROT_READ|PROT_WRITE : PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0); }
// Public Methods ////////////////////////////////////////////////////////////// void DataFlash_CRIUS_AIOP2::Init(void) { pinMode(DF_DATAOUT, OUTPUT); pinMode(DF_DATAIN, INPUT); pinMode(DF_SPICLOCK,OUTPUT); pinMode(DF_SLAVESELECT,OUTPUT); pinMode(DF_RESET,OUTPUT); // Reset the chip digitalWrite(DF_RESET,LOW); delay(1); digitalWrite(DF_RESET,HIGH); dataflash_CS_inactive_crius(); //disable device // Setup SPI Master, Mode 3, fosc/4 = 4MHz SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE3); SPI.setClockDivider(SPI_CLOCK_DIV2); // get page size: 512 or 528 df_PageSize=PageSize(); // the last page is reserved for config information df_NumPages = DF_LAST_PAGE - 1; }
static void* ReserveRegion(uintptr_t aRequest, bool aAccessible) { return VirtualAlloc((void*)aRequest, PageSize(), aAccessible ? MEM_RESERVE|MEM_COMMIT : MEM_RESERVE, aAccessible ? PAGE_EXECUTE_READWRITE : PAGE_NOACCESS); }
const Document::PageSize PDFDocument::GetPageSize( int page, float zoom, int rotation) { assert((page >= 0) && (page < GetNumPages())); const fz_irect& bbox = GetBoundingBox( GetPage(page), Transform(zoom, rotation)); return PageSize(bbox.x1 - bbox.x0, bbox.y1 - bbox.y0); }
/** Finds out if the media position "aPosToSearch" is in the cache and returns cache page information in this case. @param aPosToSearch linear media position to lookup in the cache @param aCachedPosStart if "aPosToSearch" is cached, here will be media position of this page start @return 0 if aPosToSearch isn't cached, otherwise cache page size in bytes (see also aCachedPosStart). */ TUint32 CMediaWTCache::PosCached(TInt64 aPosToSearch) { TInt nPage = FindPageByPos(aPosToSearch); if(nPage <0 ) return 0; //-- cache page containing aPos not found return PageSize(); }
void EraseFlashPage(u16 a) { // a = byte address of first word of page Assert((a & (PageSize()-1)) == 0); DwSetRegs(29, Bytes(PGERS, lo(a), hi(a))); // r29 := op (erase page), Z = first byte address of page DwSetPC(BootSect()); // Set PC that allows access to all of flash DwSend(Bytes(0x64)); // Set up for single step mode DwOut(SPMCSR(), 29); // out SPMCSR,r29 (select page erase) DwSend(Bytes(0xD2, 0x95, 0xE8, 0x33)); // spm (do page erase) DwSync(); }
void MTfile::Open(const char *filename) { char *page; if(IsOpen()) return; fileHandle=open(filename, O_RDWR|O_BINARY); if(fileHandle<0) return; // Verify that the magic words are there page=new char[PageSize()]; read(fileHandle, page, PageSize()); if(memcmp(page, magic, sizeof(magic))) { close(fileHandle); delete page; return; } delete page; SetOpen(1); }
Res VMInit(VM vm, Size size, Size grainSize, void *params) { LPVOID vbase; Size pageSize, reserved; VMParams vmParams = params; AVER(vm != NULL); AVERT(ArenaGrainSize, grainSize); AVER(size > 0); AVER(params != NULL); /* FIXME: Should have full AVERT? */ AVER(COMPATTYPE(LPVOID, Addr)); /* .assume.lpvoid-addr */ AVER(COMPATTYPE(SIZE_T, Size)); pageSize = PageSize(); /* Grains must consist of whole pages. */ AVER(grainSize % pageSize == 0); /* Check that the rounded-up sizes will fit in a Size. */ size = SizeRoundUp(size, grainSize); if (size < grainSize || size > (Size)(SIZE_T)-1) return ResRESOURCE; reserved = size + grainSize - pageSize; if (reserved < grainSize || reserved > (Size)(SIZE_T)-1) return ResRESOURCE; /* Allocate the address space. */ vbase = VirtualAlloc(NULL, reserved, vmParams->topDown ? MEM_RESERVE | MEM_TOP_DOWN : MEM_RESERVE, PAGE_NOACCESS); if (vbase == NULL) return ResRESOURCE; AVER(AddrIsAligned(vbase, pageSize)); vm->pageSize = pageSize; vm->block = vbase; vm->base = AddrAlignUp(vbase, grainSize); vm->limit = AddrAdd(vm->base, size); AVER(vm->base < vm->limit); /* .assume.not-last */ AVER(vm->limit <= AddrAdd((Addr)vm->block, reserved)); vm->reserved = reserved; vm->mapped = 0; vm->sig = VMSig; AVERT(VM, vm); EVENT3(VMInit, vm, VMBase(vm), VMLimit(vm)); return ResOK; }
void LoadPageBuffer(u16 a, const u8 *buf) { DwSetRegs(29, Bytes(SPMEN, lo(a), hi(a))); // r29 := op (write next page buffer word), Z = first byte address of page DwSend(Bytes(0x64)); // Set up for single step mode const u8 *limit = buf + PageSize(); while (buf < limit) { DwSetRegs(0, buf, 2); buf += 2; // r0 := low byte, r1 := high byte DwSetPC(BootSect()); // Set PC that allows access to all of flash DwOut(SPMCSR(), 29); // out SPMCSR,r29 (write next page buffer word) DwInst(0x95E8); // spm DwInst(0x9632); // adiw Z,2 } }
nub_size_t MachVMMemory::MaxBytesLeftInPage(task_t task, nub_addr_t addr, nub_size_t count) { const nub_size_t page_size = PageSize(task); if (page_size > 0) { nub_size_t page_offset = (addr % page_size); nub_size_t bytes_left_in_page = page_size - page_offset; if (count > bytes_left_in_page) count = bytes_left_in_page; } return count; }
/** * MesssageReceived() * * Receive messages for the view * * @param BMessage* , the message being received * @return void */ void MarginView::MessageReceived(BMessage *msg) { switch (msg->what) { case CHANGE_PAGE_SIZE: { float w; float h; msg->FindFloat("width", &w); msg->FindFloat("height", &h); SetPageSize(w, h); UpdateView(MARGIN_CHANGED); } break; case FLIP_PAGE: { BPoint p = PageSize(); SetPageSize(p.y, p.x); UpdateView(MARGIN_CHANGED); } break; case MARGIN_CHANGED: UpdateView(MARGIN_CHANGED); break; case TOP_MARGIN_CHANGED: UpdateView(TOP_MARGIN_CHANGED); break; case LEFT_MARGIN_CHANGED: UpdateView(LEFT_MARGIN_CHANGED); break; case RIGHT_MARGIN_CHANGED: UpdateView(RIGHT_MARGIN_CHANGED); break; case BOTTOM_MARGIN_CHANGED: UpdateView(BOTTOM_MARGIN_CHANGED); break; case MARGIN_UNIT_CHANGED: { int32 marginUnit; if (msg->FindInt32("marginUnit", &marginUnit) == B_OK) _SetMarginUnit((MarginUnit)marginUnit); } break; default: BView::MessageReceived(msg); break; } }
void MTfile::Create (const char *filename) { if (IsOpen()) { return; } fileHandle = open (filename, O_RDWR|O_BINARY); if (fileHandle >= 0) { close (fileHandle); return; } fileHandle = open (filename, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE); if (fileHandle < 0) { return; } SetOpen (1); /* Reserve page 0 */ char *page = new char[PageSize()]; memset (page, 0, PageSize()); memcpy (page, magic, sizeof(magic)); write (fileHandle, page, PageSize()); delete []page; }
RtfGenerator::RtfGenerator() : CodeGenerator(RTF), pageSize("a4") // Default: DIN A4 { newLineTag = "}\\par\\pard\n\\cbpat1{"; spacer = " "; // Page dimensions psMap["a3"] = PageSize(16837,23811); psMap["a4"] = PageSize(11905,16837); psMap["a5"] = PageSize(8390,11905); psMap["b4"] = PageSize(14173,20012); psMap["b5"] = PageSize(9977,14173); psMap["b6"] = PageSize(7086,9977); psMap["letter"] = PageSize(12240,15840); psMap["legal"] = PageSize(12240,20163); }
bool MachTask::EnumerateMallocFrames (MachMallocEventId event_id, mach_vm_address_t *function_addresses_buffer, uint32_t buffer_size, uint32_t *count) { if (!function_addresses_buffer || !count) return false; if (buffer_size == 0) return false; __mach_stack_logging_frames_for_uniqued_stack(m_task, event_id, &function_addresses_buffer[0], buffer_size, count); *count -= 1; if (function_addresses_buffer[*count-1] < PageSize()) *count -= 1; return (*count > 0); }
void MTfile::Deallocate(GiSTpage page) { char *buf; GiSTpage temp; if(!IsOpen()) return; // Get the old head of the list buf=new char[PageSize()]; Read(0, buf); memcpy(&temp, buf+sizeof(magic), sizeof(GiSTpage)); // Write the new head of the list memcpy(buf+sizeof(magic), &page, sizeof(GiSTpage)); Write(0, buf); // In our new head, put link to old head memcpy(buf+sizeof(magic), &temp, sizeof(GiSTpage)); Write(page, buf); delete buf; }
/* Find a spare page or evict the last from LRU list, then read data to this page from media starting from aPos @param aPos media linear position from where the data will be read to the page @return cache page number */ TUint32 CMediaWTCache::GrabReadPageL(TInt64 aPos) { //-- find a spare or page to evict TUint nPage = GrabPage(); CWTCachePage& page = *iPages[nPage]; //-- read data to this page page.iStartPos = CalcPageStartPos(aPos); __PRINT4(_L("#CMediaWTCache::GrabReadPageL() Reading page:%d, Pos=0x%x, PageStartPos=0x%x, page=0x%X"),nPage, (TUint32)aPos, (TUint32)page.iStartPos, iPages[nPage]); const TInt nErr = iDrive.ReadNonCritical(page.iStartPos, PageSize(), page.iData); if(nErr !=KErrNone) {//-- some serious problem occured during reading, invalidate cache. InvalidateCache(); User::Leave(nErr); } page.iValid = ETrue; return nPage; }
RtfGenerator::RtfGenerator() : CodeGenerator ( RTF ), pageSize ( "a4" ), // Default: DIN A4 addCharStyles ( false ), addPageColor(false), isUtf8(false), utf16Char(0), utf8SeqLen(0) { newLineTag = "}\\par\\pard\n\\cbpat1{"; spacer = " "; // Page dimensions psMap["a3"] = PageSize ( 16837,23811 ); psMap["a4"] = PageSize ( 11905,16837 ); psMap["a5"] = PageSize ( 8390,11905 ); psMap["b4"] = PageSize ( 14173,20012 ); psMap["b5"] = PageSize ( 9977,14173 ); psMap["b6"] = PageSize ( 7086,9977 ); psMap["letter"] = PageSize ( 12240,15840 ); psMap["legal"] = PageSize ( 12240,20163 ); }
void WriteFlashPage(u16 a, const u8 *buf) { // Uses r0, r1, r29, r30, r31 u8 page[MaxFlashPageSize]; Assert(PageSize() <= sizeof(page)); RenableRWW(); DwReadFlash(a, PageSize(), page); if (memcmp(buf, page, PageSize()) == 0) { ShowPageStatus(a, "unchanged"); return; } int erase = 0; for (int i=0; i<PageSize(); i++) { if (~page[i] & buf[i]) {erase=1; break;} } if (erase) { ShowPageStatus(a, "erasing"); EraseFlashPage(a); } memset(page, 0xff, PageSize()); if (memcmp(buf, page, PageSize()) == 0) { return; } ShowPageStatus(a, "loading page buffer"); LoadPageBuffer(a, buf); ShowPageStatus(a, "programming"); ProgramPage(a); RenableRWW(); }
/** Read data from the media through the directory cache. @param aPos linear media position to start reading with @param aLength how many bytes to read @param aDes data will be placed there */ void CMediaWTCache::ReadL(TInt64 aPos,TInt aLength,TDes8& aDes) { #ifdef _DEBUG if(iCacheDisabled) {//-- cache is disabled for debug purposes User::LeaveIfError(iDrive.ReadNonCritical(aPos, aLength, aDes)); return; } #endif //_DEBUG const TUint32 PageSz = PageSize();//-- cache page size //-- find out if aPos is in cache. If not, find a spare page and read data there TInt nPage = FindOrGrabReadPageL(aPos); CWTCachePage* pPage = iPages[nPage]; const TUint32 bytesToPageEnd = (TUint32)(pPage->iStartPos+PageSz - aPos); //-- number of bytes from aPos to the end of the page // __PRINT5(_L("CMediaWTCache::ReadL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, aLength, pPage->iStartPos, PageSz, bytesToPageEnd); if((TUint32)aLength <= bytesToPageEnd) {//-- the data section is in the cache page entirely, take data directly from the cache aDes.Copy(pPage->PtrInCachePage(aPos), aLength); } else {//-- Data to be read cross cache page boundary or probably we have more than 1 page to read TUint32 dataLen(aLength); //-- current data length TInt64 currMediaPos(aPos); //-- current media position //-- 1. read data that are already in the current page aDes.Copy(pPage->PtrInCachePage(currMediaPos), bytesToPageEnd); dataLen -= bytesToPageEnd; currMediaPos += bytesToPageEnd; //-- 2. read whole pages of data while(dataLen >= PageSz) { nPage = FindOrGrabReadPageL(currMediaPos); //-- find out if currMediaPos is in cache. If not, find a spare page and read data there pPage = iPages[nPage]; aDes.Append(pPage->PtrInCachePage(currMediaPos),PageSz); dataLen -= PageSz; currMediaPos += PageSz; MakePageLRU(nPage); //-- push the page to the top of the priority list } //-- 3. read the rest of the data if(dataLen >0) { nPage = FindOrGrabReadPageL(currMediaPos); //-- find out if currMediaPos is in cache. If not, find a spare page and read data there pPage = iPages[nPage]; aDes.Append(pPage->PtrInCachePage(currMediaPos), dataLen); } } //else((TUint32)aLength <= bytesToPageEnd) MakePageLRU(nPage); //-- push the page to the top of the priority list }