Cleanup stream API a bit in C client

This commit is contained in:
UnknownShadow200 2018-07-22 22:14:27 +10:00
parent 174e429f3a
commit 026a448e32
9 changed files with 74 additions and 124 deletions

View File

@ -79,8 +79,8 @@ namespace ClassicalSharp.Textures {
}
void ReadLocalFileHeader(BinaryReader reader, ZipEntry entry) {
ushort versionNeeded = reader.ReadUInt16();
ushort flags = reader.ReadUInt16();
reader.ReadUInt16(); // version needed
reader.ReadUInt16(); // flags
ushort compressionMethod = reader.ReadUInt16();
reader.ReadUInt32(); // last modified
reader.ReadUInt32(); // CRC32
@ -96,12 +96,8 @@ namespace ClassicalSharp.Textures {
if (SelectZipEntry != null && !SelectZipEntry(fileName)) return;
reader.ReadBytes(extraFieldLen);
if (versionNeeded > 20)
Utils.LogDebug("May not be able to properly extract a .zip enty with a version later than 2.0");
byte[] data = DecompressEntry(reader, compressionMethod, compressedSize, uncompressedSize);
if (data != null)
ProcessZipEntry(fileName, data, entry);
if (data != null) ProcessZipEntry(fileName, data, entry);
}
void ReadCentralDirectory(BinaryReader reader, ZipEntry[] entries) {

View File

@ -451,11 +451,9 @@ ReturnCode Bitmap_DecodePng(struct Bitmap* bmp, struct Stream* stream) {
if (dataSize != 0) return PNG_ERR_INVALID_END_SIZE;
} break;
default: {
ReturnCode result = Stream_Skip(stream, dataSize);
if (result != 0) return PNG_ERR_SKIPPING_CHUNK;
} break;
}
default:
Stream_Skip(stream, dataSize);
break;
Stream_ReadU32_BE(stream); /* Skip CRC32 */
}

View File

@ -29,10 +29,10 @@ bool Bitmap_DetectPng(UInt8* data, UInt32 len);
enum PNG_ERR {
PNG_ERR_INVALID_SIG = 307001,
PNG_ERR_INVALID_HEADER_SIZE, PNG_ERR_TOO_WIDE, PNG_ERR_TOO_TALL,
PNG_ERR_INVALID_BPP, PNG_ERR_INVALID_COL, PNG_ERR_INVALID_COL_BPP,
PNG_ERR_INVALID_BPP, PNG_ERR_INVALID_COL, PNG_ERR_INVALID_COL_BPP,
PNG_ERR_COMP_METHOD, PNG_ERR_FILTER, PNG_ERR_INTERLACED,
PNG_ERR_PAL_ENTRIES, PNG_ERR_PAL_SIZE, PNG_ERR_TRANS_COUNT, PNG_ERR_TRANS_INVALID,
PNG_ERR_INVALID_END_SIZE, PNG_ERR_SKIPPING_CHUNK,
PNG_ERR_INVALID_END_SIZE,
};
/*
Partially based off information from

View File

@ -110,14 +110,14 @@ void Lvl_Load(struct Stream* stream) {
World_Height = Stream_ReadU16_LE(&compStream);
struct LocalPlayer* p = &LocalPlayer_Instance;
p->Spawn.X = (Real32)Stream_ReadU16_LE(&compStream);
p->Spawn.Z = (Real32)Stream_ReadU16_LE(&compStream);
p->Spawn.Y = (Real32)Stream_ReadU16_LE(&compStream);
p->Spawn.X = Stream_ReadU16_LE(&compStream);
p->Spawn.Z = Stream_ReadU16_LE(&compStream);
p->Spawn.Y = Stream_ReadU16_LE(&compStream);
p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(&compStream));
p->SpawnHeadX = Math_Packed2Deg(Stream_ReadU8(&compStream));
if (header == LVL_VERSION) {
Stream_ReadU16_LE(&compStream); /* pervisit and perbuild perms */
Stream_Skip(&compStream, 1 + 1); /* permissions: (1) pervisit, (1) perbuild */
}
Map_ReadBlocks(&compStream);
@ -134,9 +134,7 @@ void Lvl_Load(struct Stream* stream) {
#define FCM_IDENTIFIER 0x0FC2AF40UL
#define FCM_REVISION 13
static void Fcm_ReadString(struct Stream* stream) {
UInt16 length = Stream_ReadU16_LE(stream);
ReturnCode code = Stream_Skip(stream, length);
ErrorHandler_CheckOrFail(code, "FCM import - skipping string");
Stream_Skip(stream, Stream_ReadU16_LE(stream));
}
void Fcm_Load(struct Stream* stream) {
@ -152,10 +150,10 @@ void Fcm_Load(struct Stream* stream) {
World_Height = Stream_ReadU16_LE(stream);
struct LocalPlayer* p = &LocalPlayer_Instance;
p->Spawn.X = Stream_ReadI32_LE(stream) / 32.0f;
p->Spawn.Y = Stream_ReadI32_LE(stream) / 32.0f;
p->Spawn.Z = Stream_ReadI32_LE(stream) / 32.0f;
p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(stream));
p->Spawn.X = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f;
p->Spawn.Y = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f;
p->Spawn.Z = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f;
p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(stream));
p->SpawnHeadX = Math_Packed2Deg(Stream_ReadU8(stream));
UInt8 tmp[26];
@ -210,9 +208,7 @@ struct NbtTag {
UInt8 Value_U8;
Int16 Value_I16;
Int32 Value_I32;
Int64 Value_I64;
Real32 Value_R32;
Real64 Value_R64;
UInt8 DataSmall[String_BufferSize(NBT_SMALL_SIZE)];
UInt8* DataBig; /* malloc for big byte arrays */
};
@ -233,21 +229,11 @@ static Int32 NbtTag_I32(struct NbtTag* tag) {
return tag->Value_I32;
}
static Int64 NbtTag_I64(struct NbtTag* tag) {
if (tag->TagID != NBT_TAG_INT64) { ErrorHandler_Fail("Expected I64 NBT tag"); }
return tag->Value_I64;
}
static Real32 NbtTag_R32(struct NbtTag* tag) {
if (tag->TagID != NBT_TAG_REAL32) { ErrorHandler_Fail("Expected R32 NBT tag"); }
return tag->Value_R32;
}
static Real64 NbtTag_R64(struct NbtTag* tag) {
if (tag->TagID != NBT_TAG_REAL64) { ErrorHandler_Fail("Expected R64 NBT tag"); }
return tag->Value_R64;
}
static UInt8 NbtTag_U8_At(struct NbtTag* tag, Int32 i) {
if (tag->TagID != NBT_TAG_INT8_ARRAY) { ErrorHandler_Fail("Expected I8_Array NBT tag"); }
if (i >= tag->DataSize) { ErrorHandler_Fail("Tried to access past bounds of I8_Array tag"); }
@ -293,13 +279,12 @@ static void Nbt_ReadTag(UInt8 typeId, bool readTagName, struct Stream* stream, s
case NBT_TAG_INT32:
tag.Value_I32 = Stream_ReadI32_BE(stream); break;
case NBT_TAG_INT64:
tag.Value_I64 = Stream_ReadI64_BE(stream); break;
Stream_Skip(stream, 8); break; /* (8) data */
case NBT_TAG_REAL32:
/* TODO: Is this union abuse even legal */
tag.Value_I32 = Stream_ReadI32_BE(stream); break;
case NBT_TAG_REAL64:
/* TODO: Is this union abuse even legal */
tag.Value_I64 = Stream_ReadI64_BE(stream); break;
Stream_Skip(stream, 8); break; /* (8) data */
case NBT_TAG_INT8_ARRAY:
count = Stream_ReadU32_BE(stream);
@ -617,9 +602,8 @@ struct JFieldDesc {
UInt8 Type;
UChar FieldName[String_BufferSize(JNAME_SIZE)];
union {
Int8 Value_I8;
UInt8 Value_U8;
Int32 Value_I32;
Int64 Value_I64;
Real32 Value_R32;
struct { UInt8* Value_Ptr; UInt32 Value_Size; };
};
@ -649,7 +633,7 @@ static void Dat_ReadFieldDesc(struct Stream* stream, struct JFieldDesc* desc) {
UChar className1[String_BufferSize(JNAME_SIZE)];
Dat_ReadString(stream, className1);
} else if (typeCode == TC_REFERENCE) {
Stream_ReadI32_BE(stream); /* handle */
Stream_Skip(stream, 4); /* (4) handle */
} else {
ErrorHandler_Fail("Unsupported type code in FieldDesc class name");
}
@ -662,8 +646,7 @@ static void Dat_ReadClassDesc(struct Stream* stream, struct JClassDesc* desc) {
if (typeCode != TC_CLASSDESC) ErrorHandler_Fail("Unsupported type code in ClassDesc header");
Dat_ReadString(stream, desc->ClassName);
Stream_ReadU64_BE(stream); /* serial version UID */
Stream_ReadU8(stream); /* flags */
Stream_Skip(stream, 8 + 1); /* (8) serial version UID, (1) flags */
desc->FieldsCount = Stream_ReadU16_BE(stream);
if (desc->FieldsCount > Array_Elems(desc->Fields)) ErrorHandler_Fail("ClassDesc has too many fields");
@ -681,14 +664,14 @@ static void Dat_ReadClassDesc(struct Stream* stream, struct JClassDesc* desc) {
static void Dat_ReadFieldData(struct Stream* stream, struct JFieldDesc* field) {
switch (field->Type) {
case JFIELD_INT8:
field->Value_I8 = Stream_ReadI8(stream); break;
field->Value_U8 = Stream_ReadU8(stream); break;
case JFIELD_REAL32:
/* TODO: Is this union abuse even legal */
field->Value_I32 = Stream_ReadI32_BE(stream); break;
case JFIELD_INT32:
field->Value_I32 = Stream_ReadI32_BE(stream); break;
case JFIELD_INT64:
field->Value_I64 = Stream_ReadI64_BE(stream); break;
Stream_Skip(stream, 8); break; /* (8) data */
case JFIELD_BOOL:
field->Value_I32 = Stream_ReadU8(stream) != 0; break;
@ -746,7 +729,7 @@ void Dat_Load(struct Stream* stream) {
Inflate_MakeStream(&compStream, &state, stream);
/* .dat header */
if (Stream_ReadI32_BE(&compStream) != 0x271BB788 || Stream_ReadU8(&compStream) != 0x02) {
if (Stream_ReadU32_BE(&compStream) != 0x271BB788 || Stream_ReadU8(&compStream) != 0x02) {
ErrorHandler_Fail("Unexpected constant in .dat file");
}

View File

@ -512,9 +512,9 @@ static void Classic_EntityTeleport(struct Stream* stream) {
static void Classic_RelPosAndOrientationUpdate(struct Stream* stream) {
EntityID id = Stream_ReadU8(stream);
Vector3 pos;
pos.X = Stream_ReadI8(stream) / 32.0f;
pos.Y = Stream_ReadI8(stream) / 32.0f;
pos.Z = Stream_ReadI8(stream) / 32.0f;
pos.X = ((Int8)Stream_ReadU8(stream)) / 32.0f;
pos.Y = ((Int8)Stream_ReadU8(stream)) / 32.0f;
pos.Z = ((Int8)Stream_ReadU8(stream)) / 32.0f;
Real32 rotY = Math_Packed2Deg(Stream_ReadU8(stream));
Real32 headX = Math_Packed2Deg(Stream_ReadU8(stream));
@ -525,9 +525,9 @@ static void Classic_RelPosAndOrientationUpdate(struct Stream* stream) {
static void Classic_RelPositionUpdate(struct Stream* stream) {
EntityID id = Stream_ReadU8(stream);
Vector3 pos;
pos.X = Stream_ReadI8(stream) / 32.0f;
pos.Y = Stream_ReadI8(stream) / 32.0f;
pos.Z = Stream_ReadI8(stream) / 32.0f;
pos.X = ((Int8)Stream_ReadU8(stream)) / 32.0f;
pos.Y = ((Int8)Stream_ReadU8(stream)) / 32.0f;
pos.Z = ((Int8)Stream_ReadU8(stream)) / 32.0f;
struct LocationUpdate update; LocationUpdate_MakePos(&update, pos, true);
Handlers_UpdateLocation(id, &update, true);
@ -749,7 +749,7 @@ static void CPE_ExtInfo(struct Stream* stream) {
/* Workaround for old MCGalaxy that send ExtEntry sync but ExtInfo async. This means
ExtEntry may sometimes arrive before ExtInfo, thus have to use += instead of = */
cpe_serverExtensionsCount += Stream_ReadI16_BE(stream);
cpe_serverExtensionsCount += Stream_ReadU16_BE(stream);
CPE_SendCpeExtInfoReply();
}
@ -827,9 +827,9 @@ static void CPE_SetTextHotkey(struct Stream* stream) {
String label = Handlers_ReadString(stream, labelBuffer);
String action = Handlers_ReadString(stream, actionBuffer);
Int32 keyCode = Stream_ReadI32_BE(stream);
UInt8 keyMods = Stream_ReadU8(stream);
if (keyCode < 0 || keyCode > 255) return;
UInt32 keyCode = Stream_ReadU32_BE(stream);
UInt8 keyMods = Stream_ReadU8(stream);
if (keyCode > 255) return;
Key key = Hotkeys_LWJGL[keyCode];
if (key == Key_None) return;
@ -850,7 +850,7 @@ static void CPE_ExtAddPlayerName(struct Stream* stream) {
UChar listNameBuffer[String_BufferSize(STRING_SIZE)];
UChar groupNameBuffer[String_BufferSize(STRING_SIZE)];
Int32 id = Stream_ReadI16_BE(stream) & 0xFF;
Int32 id = Stream_ReadU16_BE(stream) & 0xFF;
String playerName = Handlers_ReadString(stream, playerNameBuffer);
String listName = Handlers_ReadString(stream, listNameBuffer);
String groupName = Handlers_ReadString(stream, groupNameBuffer);
@ -879,7 +879,7 @@ static void CPE_ExtAddEntity(struct Stream* stream) {
}
static void CPE_ExtRemovePlayerName(struct Stream* stream) {
Int32 id = Stream_ReadI16_BE(stream) & 0xFF;
Int32 id = Stream_ReadU16_BE(stream) & 0xFF;
Handlers_RemoveTablistEntry((EntityID)id);
}
@ -899,10 +899,10 @@ static void CPE_MakeSelection(struct Stream* stream) {
p2.Z = Stream_ReadI16_BE(stream);
PackedCol col;
col.R = (UInt8)Stream_ReadI16_BE(stream);
col.G = (UInt8)Stream_ReadI16_BE(stream);
col.B = (UInt8)Stream_ReadI16_BE(stream);
col.A = (UInt8)Stream_ReadI16_BE(stream);
col.R = (UInt8)Stream_ReadU16_BE(stream);
col.G = (UInt8)Stream_ReadU16_BE(stream);
col.B = (UInt8)Stream_ReadU16_BE(stream);
col.A = (UInt8)Stream_Readu16_BE(stream);
Selections_Add(selectionId, p1, p2, col);
}
@ -914,10 +914,10 @@ static void CPE_RemoveSelection(struct Stream* stream) {
static void CPE_SetEnvCol(struct Stream* stream) {
UInt8 variable = Stream_ReadU8(stream);
Int16 r = Stream_ReadI16_BE(stream);
Int16 g = Stream_ReadI16_BE(stream);
Int16 b = Stream_ReadI16_BE(stream);
bool invalid = r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255;
UInt16 r = Stream_ReadU16_BE(stream);
UInt16 g = Stream_ReadU16_BE(stream);
UInt16 b = Stream_ReadU16_BE(stream);
bool invalid = r > 255 || g > 255 || b > 255;
PackedCol col = PACKEDCOL_CONST((UInt8)r, (UInt8)g, (UInt8)b, 255);
if (variable == 0) {

View File

@ -69,20 +69,21 @@ void Stream_SetName(struct Stream* stream, STRING_PURE String* name) {
String_AppendString(&stream->Name, name);
}
ReturnCode Stream_Skip(struct Stream* stream, UInt32 count) {
ReturnCode code = stream->Seek(stream, count, STREAM_SEEKFROM_CURRENT);
if (code == 0) return 0;
UInt8 tmp[4096];
void Stream_Skip(struct Stream* stream, UInt32 count) {
ReturnCode result = stream->Seek(stream, count, STREAM_SEEKFROM_CURRENT);
if (result == 0) return;
UInt8 tmp[3584]; /* not quite 4 KB to avoid chkstk call */
while (count > 0) {
while (count) {
UInt32 toRead = min(count, sizeof(tmp)), read;
code = stream->Read(stream, tmp, toRead, &read);
result = stream->Read(stream, tmp, toRead, &read);
if (code != 0) return code;
if (result != 0) Stream_Fail(stream, result, "Skipping data from");
if (read == 0) break; /* end of stream */
count -= read;
}
return count > 0;
if (count) Stream_Fail(stream, 0, "Skipping data from");
}
static ReturnCode Stream_DefaultIO(struct Stream* stream, UInt8* data, UInt32 count, UInt32* modified) {
@ -307,25 +308,12 @@ UInt32 Stream_ReadU32_BE(struct Stream* stream) {
((UInt32)buffer[2] << 8) | (UInt32)buffer[3]);
}
UInt64 Stream_ReadU64_BE(struct Stream* stream) {
/* infrequently called, so not bothering to optimise this. */
UInt32 hi = Stream_ReadU32_BE(stream);
UInt32 lo = Stream_ReadU32_LE(stream);
return (UInt64)(((UInt64)hi) << 32) | ((UInt64)lo);
}
void Stream_WriteU8(struct Stream* stream, UInt8 value) {
UInt32 write;
/* Inline 8 bit writing, because it is very frequently used. */
Stream_SafeWriteBlock(stream, &value, sizeof(UInt8), write);
}
void Stream_WriteU16_LE(struct Stream* stream, UInt16 value) {
UInt8 buffer[sizeof(UInt16)];
buffer[0] = (UInt8)(value ); buffer[1] = (UInt8)(value >> 8 );
Stream_Write(stream, buffer, sizeof(UInt16));
}
void Stream_WriteU16_BE(struct Stream* stream, UInt16 value) {
UInt8 buffer[sizeof(UInt16)];
buffer[0] = (UInt8)(value >> 8 ); buffer[1] = (UInt8)(value );

View File

@ -50,7 +50,7 @@ void Stream_Write(struct Stream* stream, UInt8* buffer, UInt32 count);
ReturnCode Stream_TryWrite(struct Stream* stream, UInt8* buffer, UInt32 count);
Int32 Stream_TryReadByte(struct Stream* stream);
void Stream_SetName(struct Stream* stream, STRING_PURE String* name);
ReturnCode Stream_Skip(struct Stream* stream, UInt32 count);
void Stream_Skip(struct Stream* stream, UInt32 count);
void Stream_SetDefaultOps(struct Stream* stream);
void Stream_FromFile(struct Stream* stream, void* file, STRING_PURE String* name);
@ -62,27 +62,18 @@ void Stream_ReadonlyBuffered(struct Stream* stream, struct Stream* source, void*
UInt8 Stream_ReadU8(struct Stream* stream);
#define Stream_ReadI8(stream) ((Int8)Stream_ReadU8(stream))
UInt16 Stream_ReadU16_LE(struct Stream* stream);
#define Stream_ReadI16_LE(stream) ((Int16)Stream_ReadU16_LE(stream))
UInt16 Stream_ReadU16_BE(struct Stream* stream);
#define Stream_ReadI16_BE(stream) ((Int16)Stream_ReadU16_BE(stream))
UInt32 Stream_ReadU32_LE(struct Stream* stream);
#define Stream_ReadI32_LE(stream) ((Int32)Stream_ReadU32_LE(stream))
UInt32 Stream_ReadU32_BE(struct Stream* stream);
#define Stream_ReadI16_BE(stream) ((Int16)Stream_ReadU16_BE(stream))
#define Stream_ReadI32_BE(stream) ((Int32)Stream_ReadU32_BE(stream))
UInt64 Stream_ReadU64_BE(struct Stream* stream);
#define Stream_ReadI64_BE(stream) ((Int64)Stream_ReadU64_BE(stream))
void Stream_WriteU8(struct Stream* stream, UInt8 value);
#define Stream_WriteI8(stream, value) Stream_WriteU8(stream, (UInt8)(value))
void Stream_WriteU16_LE(struct Stream* stream, UInt16 value);
#define Stream_WriteI16_LE(stream, value) Stream_WriteU16_LE(stream, (UInt16)(value))
void Stream_WriteU16_BE(struct Stream* stream, UInt16 value);
#define Stream_WriteI16_BE(stream, value) Stream_WriteU16_BE(stream, (UInt16)(value))
void Stream_WriteU32_LE(struct Stream* stream, UInt32 value);
#define Stream_WriteI32_LE(stream, value) Stream_WriteU32_LE(stream, (UInt32)(value))
void Stream_WriteU32_BE(struct Stream* stream, UInt32 value);
#define Stream_WriteI16_BE(stream, value) Stream_WriteU16_BE(stream, (UInt16)(value))
#define Stream_WriteI32_BE(stream, value) Stream_WriteU32_BE(stream, (UInt32)(value))
/* Reads a UTF8 encoded character from the given stream. Returns false if end of stream. */

View File

@ -29,16 +29,16 @@ static String Zip_ReadFixedString(struct Stream* stream, UChar* buffer, UInt16 l
static void Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntry* entry) {
struct Stream* stream = state->Input;
UInt16 versionNeeded = Stream_ReadU16_LE(stream);
UInt16 flags = Stream_ReadU16_LE(stream);
Stream_ReadU16_LE(stream); /* version needed */
Stream_ReadU16_LE(stream); /* flags */
UInt16 compressionMethod = Stream_ReadU16_LE(stream);
Stream_ReadU32_LE(stream); /* last modified */
Stream_ReadU32_LE(stream); /* CRC32 */
Int32 compressedSize = Stream_ReadI32_LE(stream);
if (compressedSize == 0) compressedSize = entry->CompressedDataSize;
Int32 uncompressedSize = Stream_ReadI32_LE(stream);
if (uncompressedSize == 0) uncompressedSize = entry->UncompressedDataSize;
UInt32 compressedSize = Stream_ReadU32_LE(stream);
if (compressedSize == 0) compressedSize = entry->CompressedSize;
UInt32 uncompressedSize = Stream_ReadU32_LE(stream);
if (uncompressedSize == 0) uncompressedSize = entry->UncompressedSize;
UInt16 fileNameLen = Stream_ReadU16_LE(stream);
UInt16 extraFieldLen = Stream_ReadU16_LE(stream);
@ -46,14 +46,9 @@ static void Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntry* ent
String filename = Zip_ReadFixedString(stream, filenameBuffer, fileNameLen);
if (!state->SelectEntry(&filename)) return;
ReturnCode code = Stream_Skip(stream, extraFieldLen);
ErrorHandler_CheckOrFail(code, "Zip - skipping local header extra");
if (versionNeeded > 20) {
Int32 version = versionNeeded;
Platform_Log1("May not be able to properly extract a .zip enty with version %i", &version);
}
Stream_Skip(stream, extraFieldLen);
struct Stream portion, compStream;
if (compressionMethod == 0) {
Stream_ReadonlyPortion(&portion, stream, uncompressedSize);
state->ProcessEntry(&filename, &portion, entry);
@ -75,9 +70,9 @@ static void Zip_ReadCentralDirectory(struct ZipState* state, struct ZipEntry* en
Stream_ReadU16_LE(stream); /* flags */
Stream_ReadU16_LE(stream); /* compresssion method*/
Stream_ReadU32_LE(stream); /* last modified */
entry->Crc32 = Stream_ReadU32_LE(stream);
entry->CompressedDataSize = Stream_ReadI32_LE(stream);
entry->UncompressedDataSize = Stream_ReadI32_LE(stream);
entry->Crc32 = Stream_ReadU32_LE(stream);
entry->CompressedSize = Stream_ReadU32_LE(stream);
entry->UncompressedSize = Stream_ReadU32_LE(stream);
UInt16 fileNameLen = Stream_ReadU16_LE(stream);
UInt16 extraFieldLen = Stream_ReadU16_LE(stream);
@ -85,21 +80,20 @@ static void Zip_ReadCentralDirectory(struct ZipState* state, struct ZipEntry* en
Stream_ReadU16_LE(stream); /* disk number */
Stream_ReadU16_LE(stream); /* internal attributes */
Stream_ReadU32_LE(stream); /* external attributes */
entry->LocalHeaderOffset = Stream_ReadI32_LE(stream);
entry->LocalHeaderOffset = Stream_ReadU32_LE(stream);
UInt32 extraDataLen = fileNameLen + extraFieldLen + fileCommentLen;
ReturnCode code = Stream_Skip(stream, extraDataLen);
ErrorHandler_CheckOrFail(code, "Zip - skipping central header extra");
Stream_Skip(stream, extraDataLen);
}
static void Zip_ReadEndOfCentralDirectory(struct ZipState* state, Int32* centralDirectoryOffset) {
static void Zip_ReadEndOfCentralDirectory(struct ZipState* state, UInt32* centralDirectoryOffset) {
struct Stream* stream = state->Input;
Stream_ReadU16_LE(stream); /* disk number */
Stream_ReadU16_LE(stream); /* disk number start */
Stream_ReadU16_LE(stream); /* disk entries */
state->EntriesCount = Stream_ReadU16_LE(stream);
Stream_ReadU32_LE(stream); /* central directory size */
*centralDirectoryOffset = Stream_ReadI32_LE(stream);
*centralDirectoryOffset = Stream_ReadU32_LE(stream);
Stream_ReadU16_LE(stream); /* comment length */
}
@ -135,7 +129,7 @@ ReturnCode Zip_Extract(struct ZipState* state) {
}
if (sig != ZIP_SIG_ENDOFCENTRALDIR) return ZIP_ERR_NO_END_OF_CENTRAL_DIR;
Int32 centralDirectoryOffset;
UInt32 centralDirectoryOffset;
Zip_ReadEndOfCentralDirectory(state, &centralDirectoryOffset);
result = stream->Seek(stream, centralDirectoryOffset, STREAM_SEEKFROM_BEGIN);
if (result != 0) return ZIP_ERR_SEEK_CENTRAL_DIR;

View File

@ -9,7 +9,7 @@ struct Stream;
struct Bitmap;
struct AsyncRequest;
struct ZipEntry { Int32 CompressedDataSize, UncompressedDataSize, LocalHeaderOffset; UInt32 Crc32; };
struct ZipEntry { UInt32 CompressedSize, UncompressedSize, LocalHeaderOffset, Crc32; };
#define ZIP_MAX_ENTRIES 2048
struct ZipState {