// // Модуль: процедуры файлового ввода-вывода для различных утилит // Компилятор: Microsoft Visual C++ v6.0 // Разработчик: 1801BM1@gmail.com // // // 20 сенятбря 2002 // Написан первый код для работы с бинарными файлами // #include "vnet32.h" extern DWORD nline; // // Открывает указанный файл исключительно для чтения // Возвращает открытый хендл или NULL в случае ошибки // При открытии специфицируется размер буфера для чтения // PFHANDLE FL_Open(char* Name, DWORD BufSize) { PFHANDLE File; int Handle, FileSize; if (NULL == Name) { return NULL; } Handle = open(Name, _O_RDONLY | _O_SEQUENTIAL | _O_BINARY, 0); if (Handle < 0) { // // Возникла ошибка // return NULL; } if (BufSize == 0) { FileSize = lseek(Handle, 0, SEEK_END); if (FileSize < 0) { close(Handle); return NULL; } if (lseek(Handle, 0, SEEK_SET) < 0) { close(Handle); return NULL; } // // Выделяем память под структуру // File = malloc(sizeof(FHANDLE) + FileSize); if (NULL == File) { close(Handle); return NULL; } // // Выполняем чтение файла целиком // File->Handle = Handle; File->Size = FileSize; File->Ptr = File->End = &File->Data[0]; File->Flags = 0; File->End += read(File->Handle, File->Ptr, FileSize); close(File->Handle); File->Handle = 0; return File; } else { // // Выделяем память под структуру // File = malloc(sizeof(FHANDLE) + BufSize); if (NULL == File) { close(Handle); return NULL; } File->Handle = Handle; File->Size = BufSize; File->Ptr = File->End = &File->Data[0]; File->Flags = 0; return File; } } // // Открывает указанный файл исключительно для записи // Возвращает открытый хендл или NULL в случае ошибки // При открытии специфицируется размер буфера для записи // PFHANDLE FL_Create(char* Name, DWORD BufSize) { PFHANDLE File; if (NULL == Name) { return NULL; } // // Сначала выделяем память под структуру // File = malloc(sizeof(FHANDLE) + BufSize); if (NULL == File) { return NULL; } File->Handle = open(Name, _O_CREAT | _O_BINARY | _O_WRONLY | _O_SEQUENTIAL | _O_TRUNC, _S_IREAD | _S_IWRITE ); if (File->Handle < 0) { // // Если возникла ошибка, то освободим выделенную память // free(File); return NULL; } File->Size = BufSize; File->Ptr = &File->Data[0]; File->End = &File->Data[BufSize]; File->Flags = FLFLG_ForWrite; return File; } // // Производит чтение текстовой строки из файла длиной не более // FL_LINSIZE байтов включая завершающий нуль. Символы CR/LF // отбрасываются // // Возвращает < 0 - в случае конца файла или ошибки чтения // >=0 - длина строки в байтах без завершающего нуля // int FL_ReadLine(PFHANDLE File, PBYTE Data) { BYTE sym; int len; len = 0; do { if (File->Ptr >= File->End) { DWORD part; // // Текущая порция данных в буфере исчерпана // прочитаем из файла новую порцию // File->Ptr = File->End = &File->Data[0]; if (File->Handle == 0) { part = 0; } else { part = read(File->Handle, File->Ptr, File->Size); } if (part == 0) { // // Достигнут конец файла, вернем буфер если // что-то еще осталось // if (len != 0) { *Data++ = 0; return len; } // // Буфер пуст, реальный конец файла // return -1; } // // Учтем, что в буфере появились новые данные // File->End += part; } // // Извлекаем очередной символ из входного файла // sym = *File->Ptr++; // // Строку ограничивается символом LF, символы CR игнорируются // if (sym == 13) continue; if (sym == 10) { *Data++ = 0; return len; } *Data++ = sym; len++; } while(len < (FL_LINSIZE-1)); // // Строка имеет слишком большую длину // ERR_ShowError(ERR_FATAL"Line %d in input source file is too long\n\r", nline); return -1; } // // Производит запись указанного числа байтов в файл // В случае ошибки возвращает ненулевое значение // DWORD FL_WriteArray(PFHANDLE File, PBYTE Data, DWORD Count) { DWORD Write = 0; // уже записано байтов DWORD Part; if (Count == 0) return 0; while(Write < Count) { if (File->Ptr >= File->End) { // // Место в буфере исчерпано, следует записать данные // из буфера на диск и модифицировать указатели // File->Ptr = &File->Data[0]; Part = write(File->Handle, File->Ptr, File->Size); if (Part != File->Size) { // // Произошла какая-то ошибка // break; } } if ((DWORD)(File->End - File->Ptr) >= (Count - Write)) { // // В буфере есть достаточно места для сохранения данных // конец буфера возможно будет достигнут, запись данных в // файл будет произведена при следующем вызове // memcpy(File->Ptr, Data + Write, Count - Write); File->Ptr += Count - Write; Write = Count; break; } // // Полностью заполним буфер и продолжаем цикл // memcpy(File->Ptr, Data + Write, File->End - File->Ptr); Write += (DWORD)(File->End - File->Ptr); File->Ptr = File->End; } // // Посмотрим, чем закончились попытка записи // if (Write == Count) return FL_ERR_SUCCESS; else return FL_ERR_WRITE; } // // Производит запись текстовой строки из буфера в файл // длиной не более FL_LINSIZE байтов включая завершающий нуль. // Автоматически добавляются символы CR/LF. // // Возвращает < 0 - в случае ошибки записи // >=0 - успешно записано // int FL_WriteLine(PFHANDLE File, PBYTE Data) { int len; len = strlen(Data); Data[len+0] = 13; Data[len+1] = 10; if(FL_WriteArray(File, Data, len+2)) { ERR_ShowError(ERR_FATAL"Output file write error\n\r"); return -1; } return 0; } // // Производит запись данных из буфера на диск, в случае // ошибки выводит сообщение возвращает ненулевое значение // DWORD FL_Flush(PFHANDLE File) { int Result; if (!(File->Flags & FLFLG_ForWrite)) { // // Файл не открыт для записи, просто выходим // return FL_ERR_SUCCESS; } if (File->Ptr != &File->Data[0]) { Result = write(File->Handle, &File->Data[0], File->Ptr - &File->Data[0]); if (Result != File->Ptr - &File->Data[0]) { ERR_ShowError(ERR_INFO"Write file error while flushing data\n\r"); return FL_ERR_WRITE; } File->Ptr = &File->Data[0]; } return FL_ERR_SUCCESS; } // // Функция закрытия открытого файла, если файл был открыт // на запись, то происходит запись отставшихся данных на диск, // также освобождается память, выделенная для буфера // void FL_Close(PFHANDLE File) { if (File->Handle != 0) { if (File->Flags & FLFLG_ForWrite) { FL_Flush(File); } close(File->Handle); } free(File); }