1 /* 2 ** DeltaRowCompression.h 3 ** Copyright 2005, Michael Pfeiffer, laplace@users.sourceforge.net. 4 ** All rights reserved. 5 ** Distributed under the terms of the MIT License. 6 */ 7 #ifndef _DELTA_ROW_COMPRESSION_H 8 #define _DELTA_ROW_COMPRESSION_H 9 10 11 #include <Debug.h> 12 13 14 class AbstractDeltaRowCompressor { 15 public: 16 AbstractDeltaRowCompressor(int rowSize, 17 uchar initialSeed); 18 virtual ~AbstractDeltaRowCompressor(); 19 20 // InitCheck returns B_OK on successful construction of this object or 21 // B_NO_MEMORY if the buffer for the seed row could not be allocated. 22 status_t InitCheck(); 23 24 // Clears the seed row to the initial seed specified in the constructor 25 void Reset(); 26 27 // Returns the size of the delta row. 28 // The size is 0 if the row is equal to the seed row (previous row). 29 // The seed row is updated only if updateSeedRow is true. 30 int CalculateSize(const uchar* row, 31 bool updateSeedRow = false); 32 33 // Compresses the row using the delta row compression algorithm. 34 // The seed row is updated. 35 void Compress(const uchar* row); 36 37 protected: 38 // append byte to delta row 39 virtual void AppendByteToDeltaRow(uchar byte) = 0; 40 41 // returns the current size of the delta row 42 inline int CurrentDeltaRowSize() 43 { 44 return fDeltaRowIndex; 45 } 46 47 private: 48 // Returns the index where seed row and row differ 49 // or -1 if both arrays are equal. 50 inline int DiffersIndex(const uchar* row, int index) 51 { 52 while (index < fSize) { 53 if (fSeedRow[index] != row[index]) 54 return index; 55 index ++; 56 } 57 return -1; 58 } 59 60 // Returns the number of bytes that row differs from seed row 61 // starting at the specified index. 62 inline int DiffersLength(const uchar* row, int index) 63 { 64 int startIndex = index; 65 while (index < fSize) { 66 if (fSeedRow[index] == row[index]) 67 break; 68 index ++; 69 } 70 return index - startIndex; 71 } 72 73 // Compresses row with delta row compression algorithm. 74 // The seed row is updated only if updateSeedRow is true. 75 // If updateDeltaRow is true the method AppendByteToDeltaRow is called. 76 int CompressRaw(const uchar* row, bool updateSeedRow, 77 bool updateDeltaRow); 78 79 // write byte to delta row and calculate size of delta row 80 void Put(uchar byte) 81 { 82 if (fUpdateDeltaRow) 83 AppendByteToDeltaRow(byte); 84 fDeltaRowIndex ++; 85 } 86 87 uchar* fSeedRow; // the seed row 88 int fSize; // the size of the seed row in bytes 89 uchar fInitialSeed; 90 // the value to initialize the seed row with 91 92 int fDeltaRowIndex; 93 // the index of the next byte to be written into 94 // the delta row 95 bool fUpdateDeltaRow; // write delta row 96 }; 97 98 99 class DeltaRowCompressor : public AbstractDeltaRowCompressor 100 { 101 public: 102 DeltaRowCompressor(int rowSize, uchar initialSeed) 103 : 104 AbstractDeltaRowCompressor(rowSize, initialSeed) 105 {} 106 107 // The delta row to be written to. 108 void SetDeltaRow(uchar* deltaRow) 109 { 110 fDeltaRow = deltaRow; 111 } 112 113 protected: 114 virtual void AppendByteToDeltaRow(uchar byte) 115 { 116 fDeltaRow[CurrentDeltaRowSize()] = byte; 117 } 118 119 private: 120 uchar* fDeltaRow; // the delta row 121 }; 122 123 #endif 124