Reading Files/Folders from disk with FAT12 in Own OS - c++

I am developing an OS, I am trying to Implement FAT12 Filesystem from an Other's OS Source Code, Finally, I can Mount a FAT12 Formatted disk and Get its FAT12 Information.
It can Read DriveName ( When 'Location = 0' ).
But When I am trying to List Directories from disk, It is not Working!
Here, This is My Code to Get Directories,
void FAT12_PrintDirectories(uint32_t Location, uint32_t numEntries, uint8_t DriveNum)
{
uint8_t read[((numEntries*32)/4096)+1];
AHCI::Port* port = AHCI::GlobalAHCI->ports[0];
port->Configure();
port->buffer = (uint8_t*)GlobalAllocator.RequestPage();
memset(port->buffer, 0, ((numEntries*32)/4096)+1);
port->Read(Location /* If I write here '0' Instead of Location, then Output is Image2 */, Location+((numEntries*32)/4096)+1, port->buffer);
for (int n = 0; n < sizeof(port->buffer); n++)
{
GlobalRenderer->PutChar(port->buffer[n]);
read[n] = port->buffer[n];
}
char drivename[12];
memset(&drivename, 0, 12);
memcpy(drivename, read, 8);
if(read[9] != ' ')
{
drivename[8] = '.';
memcpy(drivename + 9, read + 8, 3);
}
drivename[11] = 0;
// Print test read
GlobalRenderer->Next();
for (int n = 0; n < sizeof(read); n++)
{
GlobalRenderer->Print("=");
GlobalRenderer->Print(to_string((uint64_t)read[n]));
}
GlobalRenderer->Next();
GlobalRenderer->Print("Listing Dirs!");
GlobalRenderer->Next();
GlobalRenderer->Print("DriveName : ");
GlobalRenderer->Print(drivename);
GlobalRenderer->Next();
uint8_t *reads = read;
GlobalRenderer->Print("Dirs : ");
GlobalRenderer->Next();
for (unsigned int i = 0; i < numEntries; i++)
{
if(!reads[11] & 0x08 || reads[11] & 0x02 || reads[0] == 0 || reads[0] == 0xE5)
{
// Print FileName
for (uint8_t j = 0; j < 11; j++)
{
if(j == 8 && reads[j] != ' ')
{
GlobalRenderer->Print(".");
}
if(reads[j] != 0x20)
{
GlobalRenderer->Print(to_string((uint64_t)reads[j]));
}
if(reads[11] & 0x10 && j == 10)
{
GlobalRenderer->Print("/");
}
uint32_t nextCluster = (reads[27] << 8) | reads[26];
uint32_t size = *(uint32_t *)&reads[28];
}
reads += 32;
}
GlobalRenderer->Print("-");
}
}
Here It is my Calling Code for that function FAT12_PrintDirectories(dirOff, 32, 0);
This time dirOff = 2097153
Output :
After 'Dirs' text - Image1
Image2
Location = ((FAT12_MOUNT *)getDiskMount(numActiveMounts).mount)->RootDirectoryOffset*512+1;

Related

if statement doesn't work on Nucleo64 but it does on Maple mini

I have a code that works on Maple Mini but I have to change hardware to Nucleo F030r8 because it has more ADC's and it totally sucks.
In the modbus_update() function there is a check of the size of inputBuffer and the following code should run only if the value of this variable is bigger than 0.
if (inputBuffer > 0 && micros() - microsFlag >= T3_5) {
...
}
But it runs even if value of inputBuffer is exactly 0. The strange thing is that this code (with different serial ports opening method) runs perfectly on Maple Mini. Does anyone have any idea what can be be the problem?
Here is the whole code:
#define BAUDRATE 19200
#define RE_PIN PC12
#define TE_PIN PF4
#define LED_PIN LED_BUILTIN
#define SLAVE_ID 1
#define BUFFER_SIZE 256 // max frame size
#define READ_INTERNAL_REGISTERS 4 // function code
#define MIN_REGISTER_ADDRESS 30001
#define MAX_REGISTER_ADDRESS 30020
#define MAX_SENSORS_PER_ROW 10
#define SENSORS_PER_ROW 7
#define MAX_ROWS 2
#define ROWS 1
#define DEBUG true
#define INVALID_VALUE 0x7FFF
const byte INPUTS[] = {PA0, PA1, PA4, PB0, PC1, PC0};
unsigned char frame[BUFFER_SIZE];
unsigned char functionCode;
unsigned int T1;
unsigned int T1_5; // inter character time out
unsigned int T3_5; // frame delay
unsigned long millisFlag = 0;
unsigned long microsFlag = 0;
unsigned char inputBuffer = 0;
int dlyCounter = 0;
int16_t sensorVals[MAX_SENSORS_PER_ROW * MAX_ROWS];
/*
HardwareSerial *modbus = &Serial;
HardwareSerial Serial1(PA10, PA9);
HardwareSerial *debug = &Serial1;
*/
HardwareSerial debug(PA10, PA9);
void setup() {
pinMode(LED_PIN, OUTPUT);
for (int i = 0; i < SENSORS_PER_ROW; i++) {
pinMode(INPUTS[i], INPUT_PULLUP);
}
debug.begin(BAUDRATE, SERIAL_8E1);
modbus_configure(BAUDRATE, 0); // baud rate, low latency
microsFlag = micros();
}
void loop() {
readSensorVals(100);
modbus_update();
}
unsigned int modbus_update() {
unsigned char overflow = 0;
while (Serial.available()) {
if (overflow) {
Serial.read(); // empty the input buffer
} else {
if (inputBuffer == BUFFER_SIZE) {
overflow = 1;
} else {
frame[inputBuffer] = Serial.read();
inputBuffer++;
}
}
microsFlag = micros();
}
// If an overflow occurred return to the main sketch
// without responding to the request i.e. force a timeout
if (overflow) {
debug.println("Error: input buffer overflow");
return 0;
}
// if inter frame delay occurred, check the incoming package
if (inputBuffer > 0 && micros() - microsFlag >= T3_5) {
debug.println("\nIncoming frame:");
for (int i = 0; i < inputBuffer; i++) {
debug.print(frame[i], HEX);
debug.print(" ");
}
debug.println();
// check CRC
unsigned int crc = ((frame[inputBuffer - 2] << 8) | frame[inputBuffer - 1]); // combine the crc Low & High bytes
if (calculateCRC(frame, inputBuffer - 2) != crc) {
debug.println("Error: checksum failed");
inputBuffer = 0;
return 0;
}
debug.println("CRC OK");
// check ID
unsigned char id = frame[0];
if (id > 242) {
debug.println("Error: Invalid ID");
inputBuffer = 0;
return 0;
}
// check if it's a broadcast message
if (id == 0) {
debug.println("Broadcast message");
inputBuffer = 0;
return 0;
}
if (id != SLAVE_ID) {
debug.println("Not my ID");
inputBuffer = 0;
return 0;
}
debug.println("ID OK");
// check function code
functionCode = frame[1];
if (functionCode != READ_INTERNAL_REGISTERS) {
debug.println("Exception: illegal function");
exceptionResponse(1);
inputBuffer = 0;
return 0;
}
debug.println("Function code OK");
// check frame size (function 4 frame MUST be 8 bytes long)
if (inputBuffer != 8) {
// some workaround here:
//if (inputBuffer != 8 || !(inputBuffer == 9 && frame[inputBuffer] == 0)) {
debug.println("Error: inaccurate frame length");
inputBuffer = 0;
return 0;
}
debug.println("Frame size OK");
// check data address range
unsigned int noOfRegisters = ((frame[4] << 8) | frame[5]); // combine the number of register bytes
if (noOfRegisters > 125) {
debug.println("Exception: illegal data address");
exceptionResponse(2);
inputBuffer = 0;
return 0;
}
unsigned int firstRegAddress = ((frame[2] << 8) | frame[3]); // combine the starting address bytes
debug.print("First address: ");
debug.println(firstRegAddress);
unsigned int lastRegAddress = firstRegAddress + noOfRegisters - 1;
debug.print("Last address: ");
debug.println(lastRegAddress);
unsigned char noOfBytes = noOfRegisters * 2;
unsigned char responseFrameSize = 5 + noOfBytes; // ID, functionCode, noOfBytes, (dataLo + dataHi) * number of registers, crcLo, crcHi
unsigned char responseFrame[responseFrameSize];
responseFrame[0] = SLAVE_ID;
responseFrame[1] = 0x04;
responseFrame[2] = noOfBytes;
unsigned char address = 3; // PDU starts at the 4th byte
for (int index = (int)(firstRegAddress - MIN_REGISTER_ADDRESS); index <= (int)(lastRegAddress - MIN_REGISTER_ADDRESS); index++) {
int16_t temp = (index >= 0 && index < MAX_ROWS * MAX_SENSORS_PER_ROW) ? sensorVals[index] : INVALID_VALUE;
responseFrame[address] = temp >> 8; // split the register into 2 bytes
address++;
responseFrame[address] = temp & 0xFF;
address++;
}
unsigned int crc16 = calculateCRC(responseFrame, responseFrameSize - 2);
responseFrame[responseFrameSize - 2] = crc16 >> 8; // split crc into 2 bytes
responseFrame[responseFrameSize - 1] = crc16 & 0xFF;
debug.println("Frame to send:");
for (int i = 0; i < responseFrameSize; i++) {
debug.print(responseFrame[i], HEX);
debug.print(" ");
}
debug.println();
sendPacket(responseFrame, responseFrameSize);
inputBuffer = 0;
while (Serial.available()) { // empty input buffer
Serial.read();
}
}
}
void modbus_configure(long baud, unsigned char _lowLatency) {
Serial.begin(baud, SERIAL_8E1);
pinMode(TE_PIN, OUTPUT);
pinMode(RE_PIN, OUTPUT);
rxEnable(); // pin 0 & pin 1 are reserved for RX/TX. To disable set TE and RE pin < 2
if (baud == 1000000 && _lowLatency) {
T1 = 1;
T1_5 = 1;
T3_5 = 10;
} else if (baud >= 115200 && _lowLatency) {
T1 = 50;
T1_5 = 75;
T3_5 = 175;
} else if (baud > 19200) {
T1 = 500;
T1_5 = 750;
T3_5 = 1750;
} else {
T1 = 10000000 / baud;
T1_5 = 15000000 / baud; // 1T * 1.5 = T1.5
T3_5 = 35000000 / baud; // 1T * 3.5 = T3.5
}
}
void exceptionResponse(unsigned char exception) {
unsigned char responseFrameSize = 5;
unsigned char responseFrame[responseFrameSize];
responseFrame[0] = SLAVE_ID;
responseFrame[1] = (functionCode | 0x80); // set the MSB bit high, informs the master of an exception
responseFrame[2] = exception;
unsigned int crc16 = calculateCRC(responseFrame, 3); // ID, functionCode + 0x80, exception code == 3 bytes
responseFrame[3] = crc16 >> 8;
responseFrame[4] = crc16 & 0xFF;
sendPacket(responseFrame, responseFrameSize); // exception response is always 5 bytes (ID, functionCode + 0x80, exception code, 2 bytes crc)
}
unsigned int calculateCRC(unsigned char f[], byte bufferSize) {
unsigned int temp, temp2, flag;
temp = 0xFFFF;
for (unsigned char i = 0; i < bufferSize; i++) {
temp = temp ^ f[i];
for (unsigned char j = 1; j <= 8; j++) {
flag = temp & 0x0001;
temp >>= 1;
if (flag)
temp ^= 0xA001;
}
}
// Reverse byte order.
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
return temp; // the returned value is already swapped - crcLo byte is first & crcHi byte is last
}
void rxEnable() {
if (TE_PIN > 1 && RE_PIN > 1) {
digitalWrite(TE_PIN, LOW);
digitalWrite(RE_PIN, LOW);
digitalWrite(LED_PIN, LOW);
}
}
void txEnable() {
if (TE_PIN > 1 && RE_PIN > 1) {
digitalWrite(TE_PIN, HIGH);
digitalWrite(RE_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
}
}
void sendPacket(unsigned char f[], unsigned char bufferSize) {
txEnable();
delayMicroseconds(T3_5);
for (unsigned char i = 0; i < bufferSize; i++) {
Serial.write(f[i]);
}
Serial.flush();
delayMicroseconds(T3_5); // allow frame delay to indicate end of transmission
rxEnable();
}
// #param dly delay between sensor readings in milliseconds
void readSensorVals(int dly) {
if (millis() != millisFlag) {
dlyCounter++;
millisFlag = millis();
}
if (dlyCounter >= dly) { // read sensor values
for (int i = 0; i < MAX_ROWS; i++) {
for (int j = 0; j < MAX_SENSORS_PER_ROW; j++) {
int actualIndex = i * MAX_SENSORS_PER_ROW + j;
if (i < ROWS && j < SENSORS_PER_ROW) {
sensorVals[actualIndex] = random(20, 30);
//sensorVals[actualIndex] = (4096 - analogRead(INPUTS[j])) / 20 - 133;
} else {
sensorVals[actualIndex] = INVALID_VALUE;
}
}
}
dlyCounter = 0;
}
}

How to reproduce "Stack smashing detected" in C++ application

I get this error constantly in an embedded Linux application. I am trying to locate the problem and I narrowed it down to the following piece of code.
I want to solve this problem, if not I'd appreciate a couple of pointers what might have caused it.
Any suggestions how to reproduce this stack smashing problem is greately appreciated:
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0;
uint8_t i = 0;
int data[5] = {0,0,0,0,0};
int try_again = 1;
float h = 0.0;
float c = 0.0;
int try_count = 0;
const int max_tries = 30;
if (this->DHT22_SETUP_ != 1)
{
fprintf(stderr,"You havent set up Gpio !\n");
}
else
{
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 0;
//f = 0.0;
h = 0.0;
c = 0.0;
j = 0;
i = 0;
counter = 0;
laststate = HIGH;
/* pull pin down for 18 milliseconds */
pinMode( this->DHT22Pin, OUTPUT );
digitalWrite( this->DHT22Pin, LOW );
delay( 18 );
/* prepare to read the pin */
pinMode( this->DHT22Pin, INPUT );
/* detect change and read data */
for ( i = 0; i < MAX_TIMINGS; i++ )
{
counter = 0;
while ( digitalRead( this->DHT22Pin ) == laststate )
{
counter++;
delayMicroseconds( 1 );
if ( counter == 255 )
{
break;
}
}
laststate = digitalRead( this->DHT22Pin );
if ( counter == 255 )
break;
/* ignore first 3 transitions */
if ( (i >= 4) && (i % 2 == 0) )
{
/* shove each bit into the storage bytes */
data[j / 8] <<= 1;
if ( counter > 16 )
data[j / 8] |= 1;
j++;
}
}
/*
* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
* print it out if data is good
*/
if ((j >= 40) &&
(data[4] == ( (data[0] + data[1] + data[2] + data[3]) & 0xFF) ) )
{
h = (float)((data[0] << 8) + data[1]) / 10;
if ( h > 100 )
{
h = data[0]; // for DHT11
}
c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
if ( c > 125 )
{
c = data[2]; // for DHT11
}
if ( data[2] & 0x80 )
{
c = -c;
}
//f = c * 1.8f + 32;
#ifdef DEBUG
printf( "Humidity = %.1f %% Temperature = %.1f *C (%.1f *F)\n", h, c, f );
#endif
try_again = 0;
if (h == 0)
{
try_again = 1;
}
}
else
{
/* Data not good */
try_again = 1;
return 0.0;
//printf ("Data not good, skipping\n");
}
/* Return humidity */
return h;
}
Thanks in advance.
If MAX_TIMINGS is >83, and if counter doesn't reach 255 before i goes over that 83 threshold, then the detect change and read data loop is repeated that many times, and therefore the block of ignore first 3 transitions if-expression is executed >40 times (there may be some off-by-one errors in my quick analysis) and therefore j ends up being >40 which means that j / 8 will be >4 which means it is out of bounds of data array and therefore accessing data[j / 8] in that case has undefined behaviour.
Here's a nice easy way:
class T {
char big[<Some number bigger than your stack size>];
}
int main() {
T bang;
return 0;
}
The allocation of T on the stack will result in your stacksmash. What you have done is likely similar just not with a single class.

Websocket Poco can't receive big data

I downloaded and built Poco project from Poco and run WebsocketServer project in poco-1.7.6\Net\samples\WebSocketServer.
When I worked with small data that is smaller 128 KB (131072 bytes), it work perfectly. But if I work with bigger data (I need to send 20 MB), my data will be cut so server don't receive data enough.
Here is code that I copy in project:
WebSocket ws(request, response);
char *buffer = new char[1000000]; // It just receive 131072 bytes
int flags;
int n;
do
{
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
ws.sendFrame(buffer, tmp.length(), flags);
} while (n > 0 || (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
delete[] buffer;
Deframe code:
int WebSocketImpl::receiveBytes(void* buffer, int length, int)
{
char header[MAX_HEADER_LENGTH];
int n = receiveNBytes(header, 2);
if (n <= 0)
{
_frameFlags = 0;
return n;
}
poco_assert (n == 2);
Poco::UInt8 lengthByte = static_cast<Poco::UInt8>(header[1]);
int maskOffset = 0;
if (lengthByte & FRAME_FLAG_MASK) maskOffset += 4;
lengthByte &= 0x7f;
if (lengthByte > 0 || maskOffset > 0)
{
if (lengthByte + 2 + maskOffset < MAX_HEADER_LENGTH)
{
n = receiveNBytes(header + 2, lengthByte + maskOffset);
}
else
{
n = receiveNBytes(header + 2, MAX_HEADER_LENGTH - 2);
}
if (n <= 0) throw WebSocketException("Incomplete header received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
n += 2;
}
Poco::MemoryInputStream istr(header, n);
Poco::BinaryReader reader(istr, Poco::BinaryReader::NETWORK_BYTE_ORDER);
Poco::UInt8 flags;
char mask[4];
reader >> flags >> lengthByte;
_frameFlags = flags;
int payloadLength = 0;
int payloadOffset = 2;
if ((lengthByte & 0x7f) == 127)
{
Poco::UInt64 l;
reader >> l;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %Lu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
payloadOffset += 8;
}
else if ((lengthByte & 0x7f) == 126)
{
Poco::UInt16 l;
//lenBuffer = l;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %hu", l), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
payloadOffset += 2;
}
else
{
Poco::UInt8 l = lengthByte & 0x7f;
if (l > length) throw WebSocketException(Poco::format("Insufficient buffer for payload size %u", unsigned(l)), WebSocket::WS_ERR_PAYLOAD_TOO_BIG);
payloadLength = static_cast<int>(l);
}
if (lengthByte & FRAME_FLAG_MASK)
{
reader.readRaw(mask, 4);
payloadOffset += 4;
}
int received = 0;
if (payloadOffset < n)
{
std::memcpy(buffer, header + payloadOffset, n - payloadOffset);
received = n - payloadOffset;
}
if (received < payloadLength)
{
n = receiveNBytes(reinterpret_cast<char*>(buffer) + received, payloadLength - received);
if (n <= 0) throw WebSocketException("Incomplete frame received", WebSocket::WS_ERR_INCOMPLETE_FRAME);
received += n;
}
if (lengthByte & FRAME_FLAG_MASK)
{
char* p = reinterpret_cast<char*>(buffer);
for (int i = 0; i < received; i++)
{
p[i] ^= mask[i % 4];
}
}
return received;
}
Can anyone help me, please!
P/s: Sorry about my English
UPDATE: I just got this problem in Chrome. It work fine with Firefox and Edge
Setting setChunkedTransferEncoding should make it work.
In the code before the response is sent set:
response.setChunkedTransferEncoding(true);

TGA RLE compressing ( writing ) algorithm on c++

I found this code and I wonder why it does't works ..
// f is an stream
void writeTGA(ostream& f, bool rle) const{
f<<ubyte(0);//ID length
f<<ubyte(0);//Color map Type
if(rle)
f<<ubyte(10);//Image Type Code
else
f<<ubyte(2);//Image Type Code
f<<ubyte(0);//Color map stuff
f<<ubyte(0);
f<<ubyte(0);
f<<ubyte(0);
f<<ubyte(0);
f<<ubyte(0);//X Origin of Image
f<<ubyte(0);//X Origin of Image
f<<ubyte(0);//Y Origin of Image
f<<ubyte(0);//Y Origin of Image
f << ubyte(width%256);
f << ubyte(width>>8);
f << ubyte(height%256);
f << ubyte(height>>8);
f<<ubyte(24);//Image Pixels Size
f<<ubyte(32);//Image Descriptor Byte
if(rle)
{
cout<<"rleHeadHead"<<endl;
ubyte rleHead = 0;
ubyte diff[128];
int i = 0;
while(i<width*height)
{
rleHead = 1;
/* RLE */
if(i+1 < width*height)
while(pixels[i] == pixels[i+1]) {
if(i+1 >= width*height || rleHead >= 128)
break;
rleHead++;
i++;
}
if(rleHead > 1)
{
f<< (rleHead+127);
f<<pixels[i].b;
f<<pixels[i].g;
f<<pixels[i].r;
}
rleHead = 0;
/* RAW */
if(i+1 < width*height)
{
while(pixels[i+rleHead] != pixels[i+rleHead+1])
{
if( (i+rleHead+1) >= width*height || rleHead >= 128)
break;
rleHead++;
}
} else
rleHead++;
if(rleHead > 0)
{
f << (rleHead-1);
for(int j = 0; j < rleHead; j++)
{
diff[j] = pixels[i+j].b;
diff[j] = pixels[i+j].g;
diff[j] = pixels[i+j].r;
}
f.write((const char*) diff, rle*3);
i += rleHead;
}}}
else{
for(int i = 0 ; i < width*height ; i++){
f<< pixels[i].b;
f<< pixels[i].g;
f<< pixels[i].r;}
}
}
I tried to implement it and it seems not good ..
Otherwise, someone know if it exist a library or just a simple file where I can find this algorithm ?
Thanks you in advance

LZ77 compression of palmdoc

I am trying to create a utility for generating palmdoc/mobipocket format ebook files, it is said that mobi uses LZ77 compression technique to compress their records, but I found that there is quite a deviation from standard LZ77, My main source of reference is Calibre ebook creator with C implementation for palmdoc
In this file, uncompress works well, but I have not been able to compress a mobi record identically similar either using other implementation or this (Calibre code doent decompress the same).
I found some differences like, (<-- my comments follow in code)
static Py_ssize_t <-- can replaced with size_t
cpalmdoc_do_compress(buffer *b, char *output) {
Py_ssize_t i = 0, j, chunk_len, dist;
unsigned int compound;
Byte c, n;
bool found;
char *head;
buffer temp;
head = output;
temp.data = (Byte *)PyMem_Malloc(sizeof(Byte)*8); temp.len = 0;
if (temp.data == NULL) return 0;
while (i < b->len) {
c = b->data[i];
//do repeats
if ( i > 10 && (b->len - i) > 10) { <-- ignores any match outside this range
found = false;
for (chunk_len = 10; chunk_len > 2; chunk_len--) {
j = cpalmdoc_rfind(b->data, i, chunk_len);
dist = i - j;
if (j < i && dist <= 2047) { <-- 2048 window size instead of 4096
found = true;
compound = (unsigned int)((dist << 3) + chunk_len-3);
*(output++) = CHAR(0x80 + (compound >> 8 ));
*(output++) = CHAR(compound & 0xFF);
i += chunk_len;
break;
}
}
if (found) continue;
}
//write single character
i++;
if (c == 32 && i < b->len) { <-- if space is encountered skip char & check for next sequence for match otherwise do this, due to this code had wrong result.
n = b->data[i];
if ( n >= 0x40 && n <= 0x7F) {
*(output++) = CHAR(n^0x80); i++; continue;
}
}
if (c == 0 || (c > 8 && c < 0x80))
*(output++) = CHAR(c);
else { // Write binary data <-- why binary data? LZ is for text encoding
j = i;
temp.data[0] = c; temp.len = 1;
while (j < b->len && temp.len < 8) {
c = b->data[j];
if (c == 0 || (c > 8 && c < 0x80)) break;
temp.data[temp.len++] = c; j++;
}
i += temp.len - 1;
*(output++) = (char)temp.len;
for (j=0; j < temp.len; j++) *(output++) = (char)temp.data[j];
}
}
PyMem_Free(temp.data);
return output - head;
}
is this implementation correct?
PalmDoc compression essentially is byte pair compression, i.e. a variant of LZ77