int Ardb::GetRange(const DBID& db, const Slice& key, int start, int end, std::string& v) { std::string value; int ret = Get(db, key, value); if (ret < 0) { return ret; } start = RealPosition(value, start); end = RealPosition(value, end); if (start > end) { return ERR_OUTOFRANGE; } v = value.substr(start, (end - start + 1)); return ARDB_OK; }
int Ardb::SetRange(const DBID& db, const Slice& key, int start, const Slice& v) { std::string value; int ret = Get(db, key, value); if (ret < 0) { return ret; } start = RealPosition(value, start); value.resize(start); value.append(v.data(), v.size()); return Set(db, key, value) == 0 ? value.size() : 0; }
int xDeviceStream::Write( BYTE* Buffer, int count ) { if (IsClosed) { throw xException("Stream is closed. At: xDeviceStream::Write"); } #ifdef _WIN32 else if (DeviceHandle == INVALID_HANDLE_VALUE) { throw xException("Error: INVALID_HANDLE_VALUE. At: xDeviceStream::Write"); } #endif //SetPosition(Position()); // We can't write beyond the end of the stream if (Position() + count > Length()) { // Change the count to whatever we CAN write //Count = (int)((Position() >= Length()) ? 0 : Length() - Position()); throw xException("Can not write beyond end of stream! At xDeviceStream::Write"); } if (count == 0) { return 0; } int BytesWeNeedToRead = (int)(Helpers::UpToNearestSector(Position() + count) - Position()); DWORD BytesRead; BYTE* AllData = 0; // If the last time we cached data wasn't at this offset, and we're only writing to this sector if (LastReadOffset != RealPosition()) { // Cache #ifdef _WIN32 ReadFile( DeviceHandle, // Device to read from LastReadData, // Output buffer 0x200, // Read the last sector &BytesRead, // Pointer to the number of bytes read &Offset); // OVERLAPPED structure containing the offset to read from #else read(Device, LastReadData, 0x200); #endif LastReadOffset = RealPosition(); } if (BytesWeNeedToRead > 0x200) { AllData = new BYTE[BytesWeNeedToRead]; // Read the data #ifdef _WIN32 ReadFile( DeviceHandle, AllData, BytesWeNeedToRead, &BytesRead, &Offset); #else read(Device, AllData, BytesWeNeedToRead); #endif // Write over the data in memory memcpy(AllData + Position() - RealPosition(), Buffer, count); // Copy the last part of the data to our cached stuff memcpy(LastReadData, AllData + BytesWeNeedToRead - (0x200), 0x200); DetermineAndDoArraySwap(AllData, BytesWeNeedToRead); // Write the data #ifdef _WIN32 WriteFile( DeviceHandle, // Device to read from AllData, // Data to write BytesWeNeedToRead, // Amount of data to write &BytesRead, // Pointer to number of bytes written (ignore that it says BytesRead) &Offset); // OVERLAPPED structure containing the offset to write from #else write(Device, AllData, BytesWeNeedToRead); #endif delete[] AllData; } else { memcpy(LastReadData + Position() - RealPosition(), Buffer, count); void* Data = DetermineAndDoEndianSwap(AllData, BytesWeNeedToRead, sizeof(BYTE), true); if (!Data) { // Write the data #ifdef _WIN32 WriteFile( DeviceHandle, // Device to read from LastReadData, // Data to write BytesWeNeedToRead, // Amount of data to write &BytesRead, // Pointer to number of bytes written (ignore that it says BytesRead) &Offset); // OVERLAPPED structure containing the offset to write from #else write(Device, LastReadData, BytesWeNeedToRead); #endif } else { // Write the data #ifdef _WIN32 WriteFile( DeviceHandle, // Device to read from Data, // Data to write BytesWeNeedToRead, // Amount of data to write &BytesRead, // Pointer to number of bytes written (ignore that it says BytesRead) &Offset); // OVERLAPPED structure containing the offset to write from #else write(Device, Data, BytesWeNeedToRead); #endif } } SetPosition(Position() + count); return count; }
int xDeviceStream::Read( BYTE* DestBuff, int Count ) { if (IsClosed) { throw xException("Stream is closed. At: xDeviceStream::Read"); } #ifdef _WIN32 else if (DeviceHandle == INVALID_HANDLE_VALUE) { throw xException("Error: INVALID_HANDLE_VALUE. At: xDeviceStream::Read"); } #endif //SetPosition(Position()); // We can't read beyond the end of the stream if (Position() + Count > Length()) { // Change the count to whatever we CAN read Count = (int)((Position() >= Length()) ? 0 : Length() - Position()); } if (Count == 0) { return 0; } BYTE MaxSectors = (BYTE)(Helpers::UpToNearestSector(Count + (Position() - RealPosition())) / 0x200); // This is the number of sectors we have to read int BytesToShaveOffBeginning = (int)(Position() - RealPosition()); // Number of bytes to remove from the beginning of the buffer int BytesToShaveOffEnd = (int)(Helpers::UpToNearestSector(Position() + Count) - (Position() + Count)); int BytesThatAreInLastDataRead = 0x200 - BytesToShaveOffBeginning; int AllDataLength = BytesToShaveOffBeginning + Count + BytesToShaveOffEnd; /* This adds the BytesToShaveOffBeginning * all of these cool things to form * the total size that we'll be reading * (AllDataLength / 0x200 should equal MaxSectors */ if (MaxSectors != AllDataLength / 0x200) { throw xException("Assertion fail: MaxSectors != AllDataLength / 0x200. At: xDeviceStream::Read"); } BYTE* AllData = 0; DWORD BytesRead; // If the last time we cached data wasn't at this offset if (LastReadOffset != RealPosition()) { // Cache #ifdef _WIN32 ReadFile( DeviceHandle, // Device to read from LastReadData, // Output buffer 0x200, // Read the last sector &BytesRead, // Pointer to the number of bytes read &Offset); // OVERLAPPED structure containing the offset to read from #else read(Device, LastReadData, 0x200); #endif LastReadOffset = RealPosition(); } if (BytesThatAreInLastDataRead <= Count) { SetPosition(Position() + BytesThatAreInLastDataRead); } else { SetPosition(Position() + Count); } if (MaxSectors > 1) { AllData = new BYTE[AllDataLength - 0x200]; // Read for all sectors EXCEPT the last one #ifdef _WIN32 ReadFile( DeviceHandle, // Device to read from AllData, // Output buffer AllDataLength - 0x200, // Read the last sector &BytesRead, // Pointer to the number of bytes read &Offset); // OVERLAPPED structure containing the offset to read from #else read(Device, AllData, AllDataLength - 0x200); #endif SetPosition(Position() + (Count - BytesThatAreInLastDataRead)); } int countRead = ((BytesThatAreInLastDataRead <= Count) ? BytesThatAreInLastDataRead : Count); memcpy(DestBuff, LastReadData + BytesToShaveOffBeginning, countRead); if (AllData) { memcpy(DestBuff + BytesThatAreInLastDataRead, AllData, Count - BytesThatAreInLastDataRead); // Cache memcpy(&LastReadData, AllData + AllDataLength - ((0x200 * 2)), 0x200); //LastReadOffset = RealPosition(); delete[] AllData; } DetermineAndDoArraySwap(DestBuff, Count); return Count; }