mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 19:45:23 -04:00
Cleanup stream API a bit in C client
This commit is contained in:
parent
174e429f3a
commit
026a448e32
@ -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) {
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 );
|
||||
|
@ -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. */
|
||||
|
@ -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, ¢ralDirectoryOffset);
|
||||
result = stream->Seek(stream, centralDirectoryOffset, STREAM_SEEKFROM_BEGIN);
|
||||
if (result != 0) return ZIP_ERR_SEEK_CENTRAL_DIR;
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user