void Elf64_Ehdr::Load(const fs::file& f) { e_magic = Read32(f); e_class = Read8(f); e_data = Read8(f); e_curver = Read8(f); e_os_abi = Read8(f); e_abi_ver = Read64(f); e_type = Read16(f); e_machine = Read16(f); e_version = Read32(f); e_entry = Read64(f); e_phoff = Read64(f); e_shoff = Read64(f); e_flags = Read32(f); e_ehsize = Read16(f); e_phentsize = Read16(f); e_phnum = Read16(f); e_shentsize = Read16(f); e_shnum = Read16(f); e_shstrndx = Read16(f); }
kexStr kexBinFile::ReadString(void) { kexStr str; char c = 0; while(1) { if(!(c = Read8())) { break; } str += c; } return str; }
void DumpObjImports (FILE* F, unsigned long Offset) /* Dump the imports in the object file */ { ObjHeader H; Collection StrPool = AUTO_COLLECTION_INITIALIZER; unsigned Count; unsigned I; /* Seek to the header position and read the header */ FileSetPos (F, Offset); ReadObjHeader (F, &H); /* Seek to the start of the string pool and read it */ FileSetPos (F, Offset + H.StrPoolOffs); ReadStrPool (F, &StrPool); /* Seek to the start of the imports */ FileSetPos (F, Offset + H.ImportOffs); /* Output a header */ printf (" Imports:\n"); /* Read the number of imports and print it */ Count = ReadVar (F); printf (" Count:%27u\n", Count); /* Read and print all imports */ for (I = 0; I < Count; ++I) { /* Read the data for one import */ unsigned char AddrSize = Read8 (F); const char* Name = GetString (&StrPool, ReadVar (F)); unsigned Len = strlen (Name); /* Skip both line info lists */ SkipLineInfoList (F); SkipLineInfoList (F); /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", (int)(24-Len), "", Name); } /* Destroy the string pool */ DestroyStrPool (&StrPool); }
ExprNode* ReadExpr (FILE* F, ObjData* O) /* Read an expression from the given file */ { ExprNode* Expr; /* Read the node tag and handle NULL nodes */ unsigned char Op = Read8 (F); if (Op == EXPR_NULL) { return 0; } /* Create a new node */ Expr = NewExprNode (O, Op); /* Check the tag and handle the different expression types */ if (EXPR_IS_LEAF (Op)) { switch (Op) { case EXPR_LITERAL: Expr->V.IVal = Read32Signed (F); break; case EXPR_SYMBOL: /* Read the import number */ Expr->V.ImpNum = ReadVar (F); break; case EXPR_SECTION: /* Read the section number */ Expr->V.SecNum = ReadVar (F); break; default: Error ("Invalid expression op: %02X", Op); } } else { /* Not a leaf node */ Expr->Left = ReadExpr (F, O); Expr->Right = ReadExpr (F, O); } /* Return the tree */ return Expr; }
/** * Reads a null-or-return-terminated string from the stream * * If the buffer is too small to hold the entire string, it is truncated and * properly terminated. * * @param buf the output buffer * @param bufLength the size of the output buffer * @return the number of characters written to the buffer */ UInt32 IDataStream::ReadString(char * buf, UInt32 bufLength, char altTerminator, char altTerminator2) { char * traverse = buf; bool breakOnReturns = false; if((altTerminator == '\n') || (altTerminator2 == '\n')) breakOnReturns = true; ASSERT_STR(bufLength > 0, "IDataStream::ReadString: zero-sized buffer"); if(bufLength == 1) { buf[0] = 0; return 0; } bufLength--; for(UInt32 i = 0; i < bufLength; i++) { if(HitEOF()) break; UInt8 data = Read8(); if(breakOnReturns) { if(data == 0x0D) { if(Peek8() == 0x0A) Skip(1); break; } } if(!data || (data == altTerminator) || (data == altTerminator2)) { break; } *traverse++ = data; } *traverse++ = 0; return traverse - buf - 1; }
void emGifFileModel::TryStartLoading() throw(emString) { char sigver[6]; int i,flags,bgIndex,aspect; FileSize=emTryGetFileSize(GetFilePath()); errno=0; File=fopen(GetFilePath(),"rb"); if (!File) goto Err; if (fread(sigver,1,6,File)!=6) goto Err; Width=Read16(); Height=Read16(); flags=Read8(); bgIndex=Read8(); aspect=Read8(); if (ferror(File) || feof(File)) goto Err; #if 0 // Too many buggy encoders... if (aspect) PixelTallness=64.0/(aspect+15.0); else PixelTallness=1.0; #else PixelTallness=1.0; #endif if (memcmp(sigver,"GIF87a",6)!=0 && memcmp(sigver,"GIF89a",6)!=0) goto Err; if ((flags&0x80)!=0) { ColorCount=2<<(flags&7); Colors=new emColor[ColorCount]; for (i=0; i<ColorCount; i++) { Colors[i].SetRed((emByte)Read8()); Colors[i].SetGreen((emByte)Read8()); Colors[i].SetBlue((emByte)Read8()); Colors[i].SetAlpha(255); } if (ferror(File) || feof(File)) goto Err; if (bgIndex<ColorCount) { BGColor=Colors[bgIndex]; BGColor.SetAlpha(0); } } return; Err: if (errno) throw emGetErrorText(errno); else throw emString("GIF format error"); }
static void ReadO65Header (FILE* F, O65Header* H) /* Read an o65 header from the given file. The function will call Error if * something is wrong. */ { static const char Magic[3] = { O65_MAGIC_0, O65_MAGIC_1, O65_MAGIC_2 /* "o65" */ }; /* Read the marker and check it */ ReadData (F, H->marker, sizeof (H->marker)); if (H->marker[0] != O65_MARKER_0 || H->marker[1] != O65_MARKER_1) { Error ("Not an o65 object file: Invalid marker %02X %02X", H->marker[0], H->marker[1]); } /* Read the magic and check it */ ReadData (F, H->magic, sizeof (H->magic)); if (memcmp (H->magic, Magic, sizeof (H->magic)) != 0) { Error ("Not an o65 object file: Invalid magic %02X %02X %02X", H->magic[0], H->magic[1], H->magic[2]); } /* Read the version number and check it */ H->version = Read8 (F); if (H->version != O65_VERSION) { Error ("Invalid o65 version number: %02X", H->version); } /* Read the mode word */ H->mode = Read16 (F); /* Read the remainder of the header */ H->tbase = ReadO65Size (F, H); H->tlen = ReadO65Size (F, H); H->dbase = ReadO65Size (F, H); H->dlen = ReadO65Size (F, H); H->bbase = ReadO65Size (F, H); H->blen = ReadO65Size (F, H); H->zbase = ReadO65Size (F, H); H->zlen = ReadO65Size (F, H); H->stack = ReadO65Size (F, H); }
NS_IMETHODIMP nsBinaryInputStream::ReadID(nsID *aResult) { nsresult rv = Read32(&aResult->m0); NS_ENSURE_SUCCESS(rv, rv); rv = Read16(&aResult->m1); NS_ENSURE_SUCCESS(rv, rv); rv = Read16(&aResult->m2); NS_ENSURE_SUCCESS(rv, rv); for (int i = 0; i < 8; ++i) { rv = Read8(&aResult->m3[i]); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; }
Import* ReadImport (FILE* F, ObjData* Obj) /* Read an import from a file and return it */ { Import* I; /* Read the import address size */ unsigned char AddrSize = Read8 (F); /* Create a new import */ I = NewImport (AddrSize, Obj); /* Read the name */ I->Name = MakeGlobalStringId (Obj, ReadVar (F)); /* Read the line infos */ ReadLineInfoList (F, Obj, &I->DefLines); ReadLineInfoList (F, Obj, &I->RefLines); /* Check the address size */ if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) { /* Beware: This function may be called in cases where the object file ** is not read completely into memory. In this case, the file list is ** invalid. Be sure not to access it in this case. */ if (ObjHasFiles (I->Obj)) { const LineInfo* LI = GetImportPos (I); Error ("Invalid import size in for `%s', imported from %s(%u): 0x%02X", GetString (I->Name), GetSourceName (LI), GetSourceLine (LI), I->AddrSize); } else { Error ("Invalid import size in for `%s', imported from %s: 0x%02X", GetString (I->Name), GetObjFileName (I->Obj), I->AddrSize); } } /* Return the new import */ return I; }
unsigned long ReadVar (FILE* F) /* Read a variable size value from the file */ { /* The value was written to the file in 7 bit chunks LSB first. If there * are more bytes, bit 8 is set, otherwise it is clear. */ unsigned char C; unsigned long V = 0; unsigned Shift = 0; do { /* Read one byte */ C = Read8 (F); /* Encode it into the target value */ V |= ((unsigned long)(C & 0x7F)) << Shift; /* Next value */ Shift += 7; } while (C & 0x80); /* Return the value read */ return V; }
static void SkipExpr (FILE* F) /* Skip an expression from the given file */ { /* Read the node tag and handle NULL nodes */ unsigned char Op = Read8 (F); if (Op == EXPR_NULL) { return; } /* Check the tag and handle the different expression types */ if (EXPR_IS_LEAF (Op)) { switch (Op) { case EXPR_LITERAL: (void) Read32Signed (F); break; case EXPR_SYMBOL: /* Read the import number */ (void) ReadVar (F); break; case EXPR_SECTION: case EXPR_BANK: /* Read the segment number */ (void) ReadVar (F); break; default: Error ("Invalid expression op: %02X", Op); } } else { /* Not a leaf node */ SkipExpr (F); SkipExpr (F); } }
NS_IMETHODIMP nsBinaryInputStream::ReadID(nsID *aResult) { nsresult rv = Read32(&aResult->m0); if (NS_WARN_IF(NS_FAILED(rv))) return rv; rv = Read16(&aResult->m1); if (NS_WARN_IF(NS_FAILED(rv))) return rv; rv = Read16(&aResult->m2); if (NS_WARN_IF(NS_FAILED(rv))) return rv; for (int i = 0; i < 8; ++i) { rv = Read8(&aResult->m3[i]); if (NS_WARN_IF(NS_FAILED(rv))) return rv; } return NS_OK; }
bool emBmpImageFileModel::TryContinueLoading() throw(emString) { unsigned char * map; emUInt32 msk; int x,n,t,i,j,y; errno = 0; if (!L->ImagePrepared) { Image.Setup(L->Width,L->Height,L->Channels); Signal(ChangeSignal); L->ImagePrepared=true; if (L->BitsPerPixel<=8) { fseek(L->File,L->ColsOffset,SEEK_SET); L->Palette=new unsigned char[4<<L->BitsPerPixel]; memset(L->Palette,0,4<<L->BitsPerPixel); if (L->ColSize==4) { if (fread(L->Palette,1,4*L->ColsUsed,L->File)!=(size_t)(4*L->ColsUsed)) goto Err; } else { for (i=0; i<L->ColsUsed; i++) { for (j=0; j<L->ColSize; j++) { t=Read8(); if (j<4) L->Palette[i*4+j]=(unsigned char)t; } } } } else if (L->Compress==3) { fseek(L->File,L->ColsOffset,SEEK_SET); for (i=0; i<3; i++) { msk=Read32(); for (j=0; msk && (msk&1)==0; j++) msk>>=1; L->CMax[i]=msk; L->CPos[i]=j; } }
void DumpObjDbgSyms (FILE* F, unsigned long Offset) /* Dump the debug symbols from an object file */ { ObjHeader H; Collection StrPool = AUTO_COLLECTION_INITIALIZER; unsigned Count; unsigned I; /* Seek to the header position and read the header */ FileSetPos (F, Offset); ReadObjHeader (F, &H); /* Seek to the start of the string pool and read it */ FileSetPos (F, Offset + H.StrPoolOffs); ReadStrPool (F, &StrPool); /* Seek to the start of the debug syms */ FileSetPos (F, Offset + H.DbgSymOffs); /* Output a header */ printf (" Debug symbols:\n"); /* Check if the object file was compiled with debug info */ if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) { /* Print that there no debug symbols and bail out */ printf (" Count:%27u\n", 0); return; } /* Read the number of exports and print it */ Count = ReadVar (F); printf (" Count:%27u\n", Count); /* Read and print all debug symbols */ for (I = 0; I < Count; ++I) { unsigned long Value = 0; unsigned long Size = 0; unsigned ImportId = 0; unsigned ExportId = 0; /* Read the data for one symbol */ unsigned Type = ReadVar (F); unsigned char AddrSize = Read8 (F); unsigned long Owner = ReadVar (F); const char* Name = GetString (&StrPool, ReadVar (F)); unsigned Len = strlen (Name); if (SYM_IS_CONST (Type)) { Value = Read32 (F); } else { SkipExpr (F); } if (SYM_HAS_SIZE (Type)) { Size = ReadVar (F); } if (SYM_IS_IMPORT (Type)) { ImportId = ReadVar (F); } if (SYM_IS_EXPORT (Type)) { ExportId = ReadVar (F); } /* Skip both line info lists */ SkipLineInfoList (F); SkipLineInfoList (F); /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, 0)); printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, AddrSizeToStr (AddrSize)); printf (" Owner:%25lu\n", Owner); printf (" Name:%*s\"%s\"\n", (int)(24-Len), "", Name); if (SYM_IS_CONST (Type)) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } if (SYM_HAS_SIZE (Type)) { printf (" Size:%20s0x%04lX (%lu)\n", "", Size, Size); } if (SYM_IS_IMPORT (Type)) { printf (" Import:%24u\n", ImportId); } if (SYM_IS_EXPORT (Type)) { printf (" Export:%24u\n", ExportId); } } /* Destroy the string pool */ DestroyStrPool (&StrPool); }
u32 Read8_ZX(const VAddr addr) { return (u32)Read8(addr); }
Section* ReadSection (FILE* F, ObjData* O) /* Read a section from a file */ { unsigned Name; unsigned Size; unsigned long Alignment; unsigned char Type; unsigned FragCount; Segment* S; Section* Sec; /* Read the segment data */ (void) Read32 (F); /* File size of data */ Name = MakeGlobalStringId (O, ReadVar (F)); /* Segment name */ ReadVar (F); /* Segment flags (currently unused) */ Size = ReadVar (F); /* Size of data */ Alignment = ReadVar (F); /* Alignment */ Type = Read8 (F); /* Segment type */ FragCount = ReadVar (F); /* Number of fragments */ /* Print some data */ Print (stdout, 2, "Module '%s': Found segment '%s', size = %u, alignment = %lu, type = %u\n", GetObjFileName (O), GetString (Name), Size, Alignment, Type); /* Get the segment for this section */ S = GetSegment (Name, Type, GetObjFileName (O)); /* Allocate the section we will return later */ Sec = NewSection (S, Alignment, Type); /* Remember the object file this section was from */ Sec->Obj = O; /* Set up the combined segment alignment */ if (Sec->Alignment > 1) { Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment); if (Alignment > MAX_ALIGNMENT) { Error ("Combined alignment for segment '%s' is %lu which exceeds " "%lu. Last module requiring alignment was '%s'.", GetString (Name), Alignment, MAX_ALIGNMENT, GetObjFileName (O)); } else if (Alignment >= LARGE_ALIGNMENT) { Warning ("Combined alignment for segment '%s' is suspiciously " "large (%lu). Last module requiring alignment was '%s'.", GetString (Name), Alignment, GetObjFileName (O)); } S->Alignment = Alignment; } /* Start reading fragments from the file and insert them into the section . */ while (FragCount--) { Fragment* Frag; /* Read the fragment type */ unsigned char Type = Read8 (F); /* Extract the check mask from the type */ unsigned char Bytes = Type & FRAG_BYTEMASK; Type &= FRAG_TYPEMASK; /* Handle the different fragment types */ switch (Type) { case FRAG_LITERAL: Frag = NewFragment (Type, ReadVar (F), Sec); ReadData (F, Frag->LitBuf, Frag->Size); break; case FRAG_EXPR: case FRAG_SEXPR: Frag = NewFragment (Type, Bytes, Sec); Frag->Expr = ReadExpr (F, O); break; case FRAG_FILL: /* Will allocate memory, but we don't care... */ Frag = NewFragment (Type, ReadVar (F), Sec); break; default: Error ("Unknown fragment type in module '%s', segment '%s': %02X", GetObjFileName (O), GetString (S->Name), Type); /* NOTREACHED */ return 0; } /* Read the line infos into the list of the fragment */ ReadLineInfoList (F, O, &Frag->LineInfos); /* Remember the module we had this fragment from */ Frag->Obj = O; } /* Return the section */ return Sec; }
void DumpObjExports (FILE* F, unsigned long Offset) /* Dump the exports in the object file */ { ObjHeader H; Collection StrPool = AUTO_COLLECTION_INITIALIZER; unsigned Count; unsigned I; /* Seek to the header position and read the header */ FileSetPos (F, Offset); ReadObjHeader (F, &H); /* Seek to the start of the string pool and read it */ FileSetPos (F, Offset + H.StrPoolOffs); ReadStrPool (F, &StrPool); /* Seek to the start of the exports */ FileSetPos (F, Offset + H.ExportOffs); /* Output a header */ printf (" Exports:\n"); /* Read the number of exports and print it */ Count = ReadVar (F); printf (" Count:%27u\n", Count); /* Read and print all exports */ for (I = 0; I < Count; ++I) { unsigned long Value = 0; unsigned long Size = 0; unsigned char ConDes[CD_TYPE_COUNT]; const char* Name; unsigned Len; /* Read the data for one export */ unsigned Type = ReadVar (F); unsigned char AddrSize = Read8 (F); ReadData (F, ConDes, SYM_GET_CONDES_COUNT (Type)); Name = GetString (&StrPool, ReadVar (F)); Len = strlen (Name); if (SYM_IS_CONST (Type)) { Value = Read32 (F); } else { SkipExpr (F); } if (SYM_HAS_SIZE (Type)) { Size = ReadVar (F); } /* Skip both line infos lists */ SkipLineInfoList (F); SkipLineInfoList (F); /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, ConDes)); printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", (int)(24-Len), "", Name); if (SYM_IS_CONST (Type)) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } if (SYM_HAS_SIZE (Type)) { printf (" Size:%16s0x%04lX (%lu)\n", "", Size, Size); } } /* Destroy the string pool */ DestroyStrPool (&StrPool); }
/* * Apply the patch given in 'patch_filename' to the source data given * by (old_data, old_size). Write the patched output to the 'output' * file, and update the SHA context with the output data as well. * Return 0 on success. */ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const Value* patch, SinkFn sink, void* token, SHA_CTX* ctx, const Value* bonus_data) { ssize_t pos = 12; char* header = patch->data; if (patch->size < 12) { printf("patch too short to contain header\n"); return -1; } // IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW. // (IMGDIFF1, which is no longer supported, used CHUNK_NORMAL and // CHUNK_GZIP.) if (memcmp(header, "IMGDIFF2", 8) != 0) { printf("corrupt patch file header (magic number)\n"); return -1; } int num_chunks = Read4(header+8); int i; for (i = 0; i < num_chunks; ++i) { // each chunk's header record starts with 4 bytes. if (pos + 4 > patch->size) { printf("failed to read chunk %d record\n", i); return -1; } int type = Read4(patch->data + pos); pos += 4; if (type == CHUNK_NORMAL) { char* normal_header = patch->data + pos; pos += 24; if (pos > patch->size) { printf("failed to read chunk %d normal header data\n", i); return -1; } size_t src_start = Read8(normal_header); size_t src_len = Read8(normal_header+8); size_t patch_offset = Read8(normal_header+16); ApplyBSDiffPatch(old_data + src_start, src_len, patch, patch_offset, sink, token, ctx); } else if (type == CHUNK_RAW) { char* raw_header = patch->data + pos; pos += 4; if (pos > patch->size) { printf("failed to read chunk %d raw header data\n", i); return -1; } ssize_t data_len = Read4(raw_header); if (pos + data_len > patch->size) { printf("failed to read chunk %d raw data\n", i); return -1; } SHA_update(ctx, patch->data + pos, data_len); if (sink((unsigned char*)patch->data + pos, data_len, token) != data_len) { printf("failed to write chunk %d raw data\n", i); return -1; } pos += data_len; } else if (type == CHUNK_DEFLATE) { // deflate chunks have an additional 60 bytes in their chunk header. char* deflate_header = patch->data + pos; pos += 60; if (pos > patch->size) { printf("failed to read chunk %d deflate header data\n", i); return -1; } size_t src_start = Read8(deflate_header); size_t src_len = Read8(deflate_header+8); size_t patch_offset = Read8(deflate_header+16); size_t expanded_len = Read8(deflate_header+24); size_t target_len = Read8(deflate_header+32); int level = Read4(deflate_header+40); int method = Read4(deflate_header+44); int windowBits = Read4(deflate_header+48); int memLevel = Read4(deflate_header+52); int strategy = Read4(deflate_header+56); // Decompress the source data; the chunk header tells us exactly // how big we expect it to be when decompressed. // Note: expanded_len will include the bonus data size if // the patch was constructed with bonus data. The // deflation will come up 'bonus_size' bytes short; these // must be appended from the bonus_data value. size_t bonus_size = (i == 1 && bonus_data != NULL) ? bonus_data->size : 0; unsigned char* expanded_source = malloc(expanded_len); if (expanded_source == NULL) { printf("failed to allocate %d bytes for expanded_source\n", expanded_len); return -1; } z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = src_len; strm.next_in = (unsigned char*)(old_data + src_start); strm.avail_out = expanded_len; strm.next_out = expanded_source; int ret; ret = inflateInit2(&strm, -15); if (ret != Z_OK) { printf("failed to init source inflation: %d\n", ret); return -1; } // Because we've provided enough room to accommodate the output // data, we expect one call to inflate() to suffice. ret = inflate(&strm, Z_SYNC_FLUSH); if (ret != Z_STREAM_END) { printf("source inflation returned %d\n", ret); return -1; } // We should have filled the output buffer exactly, except // for the bonus_size. if (strm.avail_out != bonus_size) { printf("source inflation short by %zu bytes\n", strm.avail_out-bonus_size); return -1; } inflateEnd(&strm); if (bonus_size) { memcpy(expanded_source + (expanded_len - bonus_size), bonus_data->data, bonus_size); } // Next, apply the bsdiff patch (in memory) to the uncompressed // data. unsigned char* uncompressed_target_data; ssize_t uncompressed_target_size; if (ApplyBSDiffPatchMem(expanded_source, expanded_len, patch, patch_offset, &uncompressed_target_data, &uncompressed_target_size) != 0) { return -1; } // Now compress the target data and append it to the output. // we're done with the expanded_source data buffer, so we'll // reuse that memory to receive the output of deflate. unsigned char* temp_data = expanded_source; ssize_t temp_size = expanded_len; if (temp_size < 32768) { // ... unless the buffer is too small, in which case we'll // allocate a fresh one. free(temp_data); temp_data = malloc(32768); temp_size = 32768; } // now the deflate stream strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = uncompressed_target_size; strm.next_in = uncompressed_target_data; ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy); do { strm.avail_out = temp_size; strm.next_out = temp_data; ret = deflate(&strm, Z_FINISH); ssize_t have = temp_size - strm.avail_out; if (sink(temp_data, have, token) != have) { printf("failed to write %ld compressed bytes to output\n", (long)have); return -1; } SHA_update(ctx, temp_data, have); } while (ret != Z_STREAM_END); deflateEnd(&strm); free(temp_data); free(uncompressed_target_data); } else { printf("patch chunk %d is unknown type %d\n", i, type); return -1; } } return 0; }
void DumpObjOptions (FILE* F, unsigned long Offset) /* Dump the file options */ { ObjHeader H; Collection StrPool = AUTO_COLLECTION_INITIALIZER; unsigned Count; unsigned I; /* Seek to the header position and read the header */ FileSetPos (F, Offset); ReadObjHeader (F, &H); /* Seek to the start of the string pool and read it */ FileSetPos (F, Offset + H.StrPoolOffs); ReadStrPool (F, &StrPool); /* Seek to the start of the options */ FileSetPos (F, Offset + H.OptionOffs); /* Output a header */ printf (" Options:\n"); /* Read the number of options and print it */ Count = ReadVar (F); printf (" Count:%27u\n", Count); /* Read and print all options */ for (I = 0; I < Count; ++I) { const char* ArgStr; unsigned ArgLen; /* Read the type of the option and the value */ unsigned char Type = Read8 (F); unsigned long Val = ReadVar (F); /* Get the type of the argument */ unsigned char ArgType = Type & OPT_ARGMASK; /* Determine which option follows */ const char* TypeDesc; switch (Type) { case OPT_COMMENT: TypeDesc = "OPT_COMMENT"; break; case OPT_AUTHOR: TypeDesc = "OPT_AUTHOR"; break; case OPT_TRANSLATOR:TypeDesc = "OPT_TRANSLATOR"; break; case OPT_COMPILER: TypeDesc = "OPT_COMPILER"; break; case OPT_OS: TypeDesc = "OPT_OS"; break; case OPT_DATETIME: TypeDesc = "OPT_DATETIME"; break; default: TypeDesc = "OPT_UNKNOWN"; break; } /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); switch (ArgType) { case OPT_ARGSTR: ArgStr = GetString (&StrPool, Val); ArgLen = strlen (ArgStr); printf (" Data:%*s\"%s\"\n", (int)(24-ArgLen), "", ArgStr); break; case OPT_ARGNUM: printf (" Data:%26lu", Val); if (Type == OPT_DATETIME) { /* Print the time as a string */ printf (" (%s)", TimeToStr (Val)); } printf ("\n"); break; default: /* Unknown argument type. This means that we cannot determine * the option length, so we cannot proceed. */ Error ("Unknown option type: 0x%02X", Type); break; } } /* Destroy the string pool */ DestroyStrPool (&StrPool); }
static void ReadO65RelocInfo (FILE* F, const O65Data* D, Collection* Reloc) /* Read relocation data for one segment */ { /* Relocation starts at (start address - 1) */ unsigned long Offs = (unsigned long) -1L; while (1) { O65Reloc* R; /* Read the next relocation offset */ unsigned char C = Read8 (F); if (C == 0) { /* End of relocation table */ break; } /* Create a new relocation entry */ R = xmalloc (sizeof (*R)); /* Handle overflow bytes */ while (C == 0xFF) { Offs += 0xFE; C = Read8 (F); } /* Calculate the final offset */ R->Offs = (Offs += C); /* Read typebyte and segment id */ C = Read8 (F); R->Type = (C & O65_RTYPE_MASK); R->SegID = (C & O65_SEGID_MASK); /* Read an additional relocation value if there is one */ R->SymIdx = (R->SegID == O65_SEGID_UNDEF)? ReadO65Size (F, &D->Header) : 0; switch (R->Type) { case O65_RTYPE_HIGH: if ((D->Header.mode & O65_RELOC_MASK) == O65_RELOC_BYTE) { /* Low byte follows */ R->Val = Read8 (F); } else { /* Low byte is zero */ R->Val = 0; } break; case O65_RTYPE_SEG: /* Low 16 byte of the segment address follow */ R->Val = Read16 (F); break; default: R->Val = 0; break; } /* Insert this relocation entry into the collection */ CollAppend (Reloc, R); } }
/** * Reads and returns an 8-bit value from the stream without advancing the stream's position */ UInt8 IDataStream::Peek8(void) { IDataStream_PositionSaver saver(this); return Read8(); }
/* * Apply the patch given in 'patch_filename' to the source data given * by (old_data, old_size). Write the patched output to the 'output' * file, and update the SHA context with the output data as well. * Return 0 on success. */ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, const char* patch_filename, SinkFn sink, void* token, SHA_CTX* ctx) { FILE* f; if ((f = fopen(patch_filename, "rb")) == NULL) { printf("failed to open patch file\n"); return -1; } unsigned char header[12]; if (fread(header, 1, 12, f) != 12) { printf("failed to read patch file header\n"); return -1; } // IMGDIFF1 uses CHUNK_NORMAL and CHUNK_GZIP. // IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW. if (memcmp(header, "IMGDIFF", 7) != 0 || (header[7] != '1' && header[7] != '2')) { printf("corrupt patch file header (magic number)\n"); return -1; } int num_chunks = Read4(header+8); int i; for (i = 0; i < num_chunks; ++i) { // each chunk's header record starts with 4 bytes. unsigned char chunk[4]; if (fread(chunk, 1, 4, f) != 4) { printf("failed to read chunk %d record\n", i); return -1; } int type = Read4(chunk); if (type == CHUNK_NORMAL) { unsigned char normal_header[24]; if (fread(normal_header, 1, 24, f) != 24) { printf("failed to read chunk %d normal header data\n", i); return -1; } size_t src_start = Read8(normal_header); size_t src_len = Read8(normal_header+8); size_t patch_offset = Read8(normal_header+16); printf("CHUNK %d: normal patch offset %d\n", i, patch_offset); ApplyBSDiffPatch(old_data + src_start, src_len, patch_filename, patch_offset, sink, token, ctx); } else if (type == CHUNK_GZIP) { // This branch is basically a duplicate of the CHUNK_DEFLATE // branch, with a bit of extra processing for the gzip header // and footer. I've avoided factoring the common code out since // this branch will just be deleted when we drop support for // IMGDIFF1. // gzip chunks have an additional 64 + gzip_header_len + 8 bytes // in their chunk header. unsigned char* gzip = malloc(64); if (fread(gzip, 1, 64, f) != 64) { printf("failed to read chunk %d initial gzip header data\n", i); return -1; } size_t gzip_header_len = Read4(gzip+60); gzip = realloc(gzip, 64 + gzip_header_len + 8); if (fread(gzip+64, 1, gzip_header_len+8, f) != gzip_header_len+8) { printf("failed to read chunk %d remaining gzip header data\n", i); return -1; } size_t src_start = Read8(gzip); size_t src_len = Read8(gzip+8); size_t patch_offset = Read8(gzip+16); size_t expanded_len = Read8(gzip+24); size_t target_len = Read8(gzip+32); int gz_level = Read4(gzip+40); int gz_method = Read4(gzip+44); int gz_windowBits = Read4(gzip+48); int gz_memLevel = Read4(gzip+52); int gz_strategy = Read4(gzip+56); printf("CHUNK %d: gzip patch offset %d\n", i, patch_offset); // Decompress the source data; the chunk header tells us exactly // how big we expect it to be when decompressed. unsigned char* expanded_source = malloc(expanded_len); if (expanded_source == NULL) { printf("failed to allocate %d bytes for expanded_source\n", expanded_len); return -1; } z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = src_len - (gzip_header_len + 8); strm.next_in = (unsigned char*)(old_data + src_start + gzip_header_len); strm.avail_out = expanded_len; strm.next_out = expanded_source; int ret; ret = inflateInit2(&strm, -15); if (ret != Z_OK) { printf("failed to init source inflation: %d\n", ret); return -1; } // Because we've provided enough room to accommodate the output // data, we expect one call to inflate() to suffice. ret = inflate(&strm, Z_SYNC_FLUSH); if (ret != Z_STREAM_END) { printf("source inflation returned %d\n", ret); return -1; } // We should have filled the output buffer exactly. if (strm.avail_out != 0) { printf("source inflation short by %d bytes\n", strm.avail_out); return -1; } inflateEnd(&strm); // Next, apply the bsdiff patch (in memory) to the uncompressed // data. unsigned char* uncompressed_target_data; ssize_t uncompressed_target_size; if (ApplyBSDiffPatchMem(expanded_source, expanded_len, patch_filename, patch_offset, &uncompressed_target_data, &uncompressed_target_size) != 0) { return -1; } // Now compress the target data and append it to the output. // start with the gzip header. sink(gzip+64, gzip_header_len, token); SHA_update(ctx, gzip+64, gzip_header_len); // we're done with the expanded_source data buffer, so we'll // reuse that memory to receive the output of deflate. unsigned char* temp_data = expanded_source; ssize_t temp_size = expanded_len; if (temp_size < 32768) { // ... unless the buffer is too small, in which case we'll // allocate a fresh one. free(temp_data); temp_data = malloc(32768); temp_size = 32768; } // now the deflate stream strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = uncompressed_target_size; strm.next_in = uncompressed_target_data; ret = deflateInit2(&strm, gz_level, gz_method, gz_windowBits, gz_memLevel, gz_strategy); do { strm.avail_out = temp_size; strm.next_out = temp_data; ret = deflate(&strm, Z_FINISH); size_t have = temp_size - strm.avail_out; if (sink(temp_data, have, token) != have) { printf("failed to write %d compressed bytes to output\n", have); return -1; } SHA_update(ctx, temp_data, have); } while (ret != Z_STREAM_END); deflateEnd(&strm); // lastly, the gzip footer. sink(gzip+64+gzip_header_len, 8, token); SHA_update(ctx, gzip+64+gzip_header_len, 8); free(temp_data); free(uncompressed_target_data); free(gzip); } else if (type == CHUNK_RAW) { unsigned char raw_header[4]; if (fread(raw_header, 1, 4, f) != 4) { printf("failed to read chunk %d raw header data\n", i); return -1; } size_t data_len = Read4(raw_header); printf("CHUNK %d: raw data %d\n", i, data_len); unsigned char* temp = malloc(data_len); if (fread(temp, 1, data_len, f) != data_len) { printf("failed to read chunk %d raw data\n", i); return -1; } SHA_update(ctx, temp, data_len); if (sink(temp, data_len, token) != data_len) { printf("failed to write chunk %d raw data\n", i); return -1; } } else if (type == CHUNK_DEFLATE) { // deflate chunks have an additional 60 bytes in their chunk header. unsigned char deflate_header[60]; if (fread(deflate_header, 1, 60, f) != 60) { printf("failed to read chunk %d deflate header data\n", i); return -1; } size_t src_start = Read8(deflate_header); size_t src_len = Read8(deflate_header+8); size_t patch_offset = Read8(deflate_header+16); size_t expanded_len = Read8(deflate_header+24); size_t target_len = Read8(deflate_header+32); int level = Read4(deflate_header+40); int method = Read4(deflate_header+44); int windowBits = Read4(deflate_header+48); int memLevel = Read4(deflate_header+52); int strategy = Read4(deflate_header+56); printf("CHUNK %d: deflate patch offset %d\n", i, patch_offset); // Decompress the source data; the chunk header tells us exactly // how big we expect it to be when decompressed. unsigned char* expanded_source = malloc(expanded_len); if (expanded_source == NULL) { printf("failed to allocate %d bytes for expanded_source\n", expanded_len); return -1; } z_stream strm; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = src_len; strm.next_in = (unsigned char*)(old_data + src_start); strm.avail_out = expanded_len; strm.next_out = expanded_source; int ret; ret = inflateInit2(&strm, -15); if (ret != Z_OK) { printf("failed to init source inflation: %d\n", ret); return -1; } // Because we've provided enough room to accommodate the output // data, we expect one call to inflate() to suffice. ret = inflate(&strm, Z_SYNC_FLUSH); if (ret != Z_STREAM_END) { printf("source inflation returned %d\n", ret); return -1; } // We should have filled the output buffer exactly. if (strm.avail_out != 0) { printf("source inflation short by %d bytes\n", strm.avail_out); return -1; } inflateEnd(&strm); // Next, apply the bsdiff patch (in memory) to the uncompressed // data. unsigned char* uncompressed_target_data; ssize_t uncompressed_target_size; if (ApplyBSDiffPatchMem(expanded_source, expanded_len, patch_filename, patch_offset, &uncompressed_target_data, &uncompressed_target_size) != 0) { return -1; } // Now compress the target data and append it to the output. // we're done with the expanded_source data buffer, so we'll // reuse that memory to receive the output of deflate. unsigned char* temp_data = expanded_source; ssize_t temp_size = expanded_len; if (temp_size < 32768) { // ... unless the buffer is too small, in which case we'll // allocate a fresh one. free(temp_data); temp_data = malloc(32768); temp_size = 32768; } // now the deflate stream strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = uncompressed_target_size; strm.next_in = uncompressed_target_data; ret = deflateInit2(&strm, level, method, windowBits, memLevel, strategy); do { strm.avail_out = temp_size; strm.next_out = temp_data; ret = deflate(&strm, Z_FINISH); size_t have = temp_size - strm.avail_out; if (sink(temp_data, have, token) != have) { printf("failed to write %d compressed bytes to output\n", have); return -1; } SHA_update(ctx, temp_data, have); } while (ret != Z_STREAM_END); deflateEnd(&strm); free(temp_data); free(uncompressed_target_data); } else { printf("patch chunk %d is unknown type %d\n", i, type); return -1; } } return 0; }
/// reads unsigned short unsigned short Read16() { unsigned short us = Read8(); // low byte us |= static_cast<unsigned short>(Read8()) << 8; // high byte return us; }
u16 TestEnvironment::TestMemory::Read16(VAddr addr) { return Read8(addr) | static_cast<u16>(Read8(addr + 1)) << 8; }
bool emGifFileModel::TryContinueLoading() throw(emString) { char * p; Render * r; Render * * pr; char tmp[256]; int b,i; errno=0; if (InLoadingRenderData) { r=RenderArray[RenderCount-1]; b=Read8(); if (b) { if (r->DataFill+b>r->DataSize) { r->DataSize+=65536; p=new char[r->DataSize]; if (r->Data) { memcpy(p,r->Data,r->DataFill); delete [] r->Data; } r->Data=p; } if (fread(r->Data+r->DataFill,1,b,File)!=(size_t)b) goto Err; r->DataFill+=b; } else { if (r->DataFill<=0) goto Err; if (r->DataFill<r->DataSize) { p=new char[r->DataFill]; memcpy(p,r->Data,r->DataFill); delete [] r->Data; r->Data=p; r->DataSize=r->DataFill; } InLoadingRenderData=false; } if (ferror(File) || feof(File)) goto Err; return false; } b=Read8(); if (ferror(File)) { goto Err; } else if (feof(File) || b==0x3B) { fclose(File); File=NULL; if (!PostProcess()) goto Err; return true; } else if (b==0x2c) { r=new Render; r->Disposal=NextDisposal; r->Delay=NextDelay; r->Transparent=NextTransparent; r->UserInput=NextUserInput; r->Interlaced=false; r->X=Read16(); r->Y=Read16(); r->Width=Read16(); r->Height=Read16(); r->ColorCount=0; r->DataSize=0; r->DataFill=0; r->Colors=NULL; r->Data=NULL; if (RenderCount>=RenderArraySize) { RenderArraySize+=64; pr=new Render*[RenderArraySize]; if (RenderArray) { for (i=0; i<RenderCount; i++) pr[i]=RenderArray[i]; delete [] RenderArray; } RenderArray=pr; } RenderArray[RenderCount++]=r; b=Read8(); if (ferror(File) || feof(File)) goto Err; if ((b&0x40)!=0) r->Interlaced=true; if ((b&0x80)!=0) { r->ColorCount=2<<(b&7); r->Colors=new emColor[r->ColorCount]; for (i=0; i<r->ColorCount; i++) { r->Colors[i].SetRed((emByte)Read8()); r->Colors[i].SetGreen((emByte)Read8()); r->Colors[i].SetBlue((emByte)Read8()); r->Colors[i].SetAlpha(255); } if (ferror(File) || feof(File)) goto Err; } else { if (ColorCount<=0) goto Err; } r->MinCodeSize=Read8(); if (r->MinCodeSize<1 || r->MinCodeSize>8) goto Err; NextDisposal=0; NextUserInput=false; NextDelay=0; NextTransparent=-1; InLoadingRenderData=true; } else if (b==0x21) { b=Read8(); if (b==0xfe) { if (Comment.GetLen()>=65536) goto Err; for (i=0;;) { b=Read8(); if (ferror(File) || feof(File)) goto Err; if (!b) break; i+=b; if (i>=65536) goto Err; if (fread(tmp,1,b,File)!=(size_t)b) goto Err; tmp[b]=0; Comment+=tmp; } } else if (b==0xf9) { if (Read8()!=4) goto Err; b=Read8(); NextDelay=Read16(); NextTransparent=Read8(); Read8(); if (ferror(File) || feof(File)) goto Err; NextDisposal=(b>>2)&7; if (NextDisposal==4) NextDisposal=3; if (NextDisposal>3) goto Err; NextUserInput=(b&0x02) ? true : false; if ((b&0x01)==0) NextTransparent=-1; } else if (b==0x01) {
short kexBinFile::Read16(void) { int result; result = Read8(); result |= Read8() << 8; return result; }
int GameState::Stocks(int player) { UpdateAddress(player - 1); return Read8(player - 1); }
/* * Reformat an Apple /// Business BASIC program into a text format that * mimics the output of the "LIST" command. */ int ReformatBusiness::Process(const ReformatHolder* pHolder, ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part, ReformatOutput* pOutput) { const uint8_t* srcPtr = pHolder->GetSourceBuf(part); long srcLen = pHolder->GetSourceLen(part); long length = srcLen; int retval = -1; int nestLevels = 0; if (srcLen > 65536) fUseRTF = false; if (fUseRTF) { if (id != ReformatHolder::kReformatBusiness_Hilite) fUseRTF = false; } RTFBegin(kRTFFlagColorTable); /* * Make sure there's enough here to get started. We want to return an * "okay" result because we want this treated like a reformatted empty * BASIC program rather than a non-BASIC file. */ if (length < 2) { LOGI(" BA3 truncated?"); //fExpBuf.CreateWorkBuf(); BufPrintf("\r\n"); goto done; } uint16_t fileLength; fileLength = Read16(&srcPtr, &length); LOGI(" BA3 internal file length is: %d", fileLength); while (length > 0) { uint16_t increment; uint16_t extendedToken; uint16_t lineNum; bool inQuote = false; bool inRem = false; bool firstData = true; bool literalYet = false; increment = Read8(&srcPtr, &length); LOGI(" BA3 increment to next line is: %d", increment); if (increment == 0) { /* ProDOS sticks an extra byte on the end? */ if (length > 1) { LOGI(" BA3 ended early; len is %d", length); } break; } /* print line number */ RTFSetColor(kLineNumColor); lineNum = Read16(&srcPtr, &length); LOGI(" BA3 line number: %d", lineNum); BufPrintf(" %u ", lineNum); RTFSetColor(kDefaultColor); if (nestLevels > 0) { for (int i =0; i < nestLevels; i++) BufPrintf(" "); } /* print a line */ while (*srcPtr != 0 && length > 0) { if (*srcPtr & 0x80) { /* token */ //RTFBoldOn(); literalYet = false; RTFSetColor(kKeywordColor); if (*srcPtr == 0x81) { // Token is FOR - indent nestLevels ++; } else if (*srcPtr == 0x82) { // Token is NEXT - outdent nestLevels --; } if (!firstData) BufPrintf(" "); if (((*srcPtr) & 0x7f) == 0x7f) { extendedToken = Read8(&srcPtr, &length); BufPrintf("%s", &gExtendedBusinessTokens[((*srcPtr) & 0x7f) * 10]); // We need to have some tokens NOT add a space after them. if ((*srcPtr == 0x80) || // TAB( (*srcPtr == 0x82) || // SPC( (*srcPtr == 0x9d) || // SGN( (*srcPtr == 0x9e) || // INT( (*srcPtr == 0x9f) || // ABS( (*srcPtr == 0xa1) || // TYP( (*srcPtr == 0xa2) || // REC( (*srcPtr == 0xad) || // PDL( (*srcPtr == 0xae) || // BUTTON( (*srcPtr == 0xaf) || // SQR( (*srcPtr == 0xb0) || // RND( (*srcPtr == 0xb1) || // LOG( (*srcPtr == 0xb2) || // EXP( (*srcPtr == 0xb3) || // COS( (*srcPtr == 0xb4) || // SIN( (*srcPtr == 0xb5) || // TAN( (*srcPtr == 0xb6) || // ATN( (*srcPtr == 0xc3) || // STR$( (*srcPtr == 0xc4) || // HEX$( (*srcPtr == 0xc5) || // CHR$( (*srcPtr == 0xc6) || // LEN( (*srcPtr == 0xc7) || // VAL( (*srcPtr == 0xc8) || // ASC( (*srcPtr == 0xc9) || // TEN( (*srcPtr == 0xcc) || // CONV( (*srcPtr == 0xcd) || // CONV&( (*srcPtr == 0xce) || // CONV$( (*srcPtr == 0xcf) || // CONV%( (*srcPtr == 0xd0) || // LEFT$( (*srcPtr == 0xd1) || // RIGHT$( (*srcPtr == 0xd2) || // MID$( (*srcPtr == 0xd3)) // INSTR$( firstData = true; else firstData = false; } else { BufPrintf("%s", &gBusinessTokens[((*srcPtr) & 0x7f) * 10]); // We need to have some tokens NOT add a space after them. if ((*srcPtr == 0x99) || // HPOS (*srcPtr == 0x9a) || // VPOS (*srcPtr == 0x9f) || // TIME$ (*srcPtr == 0xa0) || // DATE$ (*srcPtr == 0xa1) || // PREFIX$ (*srcPtr == 0xa2) || // EXFN. (*srcPtr == 0xa3) || // EXFN%. (*srcPtr == 0xb0) || // SUB$(. (*srcPtr == 0xb6) || // SCALE( (*srcPtr == 0xc0) || // REM (*srcPtr == 0xe3)) // SPC( firstData = true; else firstData = false; } //RTFBoldOff(); RTFSetColor(kDefaultColor); if (*srcPtr == 0xc0) { // REM -- do rest of line in green RTFSetColor(kCommentColor); inRem = true; } } else { /* simple chracter */ if (*srcPtr == ':') // Reset line if we have a colon firstData = true; if (!firstData) { if (!literalYet) { BufPrintf(" "); literalYet = true; } } if (fUseRTF) { if (*srcPtr == '"' && !inRem) { if (!inQuote) { RTFSetColor(kStringColor); RTFPrintChar(*srcPtr); } else { RTFPrintChar(*srcPtr); RTFSetColor(kDefaultColor); } inQuote = !inQuote; } else if (*srcPtr == ':' && !inRem && !inQuote) { RTFSetColor(kColonColor); RTFPrintChar(*srcPtr); RTFSetColor(kDefaultColor); } else { RTFPrintChar(*srcPtr); } } else { BufPrintf("%c", *srcPtr); } } srcPtr++; length--; } if (inQuote || inRem) RTFSetColor(kDefaultColor); inQuote = inRem = false; srcPtr++; length--; if (!length) { LOGI(" BA3 truncated in mid-line"); break; } RTFNewPara(); } done: RTFEnd(); SetResultBuffer(pOutput); retval = 0; //bail: return retval; }
static int read_movie_header(FILE* fd, SMovie* movie) { uint8 header[SMV_HEADER_SIZE]; if(fread(header, 1, SMV_HEADER_SIZE, fd) != SMV_HEADER_SIZE) return WRONG_FORMAT; const uint8* ptr=header; uint32 magic=Read32(ptr); if(magic!=SMV_MAGIC) return WRONG_FORMAT; uint32 version=Read32(ptr); if(version>SMV_VERSION) return WRONG_VERSION; // we can still get this basic info from v1 movies movie->MovieId=Read32(ptr); movie->RerecordCount=Read32(ptr); movie->MaxFrame=Read32(ptr); movie->Version=version; int i, p, j; for(j = 0; j < 2; j++) { if((j == 0 && version != 3) || (j == 1 && version == 3)) { movie->ControllersMask=Read8(ptr); movie->Opts=Read8(ptr); Read8(ptr); // reserved byte movie->SyncFlags=Read8(ptr); movie->SaveStateOffset=Read32(ptr); movie->ControllerDataOffset=Read32(ptr); } // not part of original v1 SMV format: if((j == 1 && version > 3) || (j == 0 && version == 3)) { movie->MaxSample=Read32(ptr); movie->PortType[0]=Read8(ptr); movie->PortType[1]=Read8(ptr); for(p=0;p<2;p++) for(i=0;i<4;i++) movie->PortIDs[p][i]=Read8(ptr); } } if(version<3) return WRONG_VERSION; // needs to be at least 1 sample per frame. So, assume that to make hex editing easier, at least for non-peripheral-using movies. if(movie->MaxSample < movie->MaxFrame) movie->MaxSample = movie->MaxFrame; ptr += 18; // reserved bytes assert(ptr-header==SMV_HEADER_SIZE); return SUCCESS; }
Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; unsigned I; Export* E; /* Read the type */ unsigned Type = ReadVar (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = SYM_GET_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte ** which contains the type and the priority. In memory, we will use ** an array of types which contain the priority. */ for (I = 0; I < ConDesCount; ++I) { E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]); } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (SYM_IS_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Read the size */ if (SYM_HAS_SIZE (Type)) { E->Size = ReadVar (F); } /* Last are the locations */ ReadLineInfoList (F, O, &E->DefLines); ReadLineInfoList (F, O, &E->RefLines); /* If this symbol is exported as a condes, and the condes type declares a ** forced import, add this import to the object module. */ for (I = 0; I < CD_TYPE_COUNT; ++I) { const ConDesImport* CDI; if (E->ConDes[I] != CD_PRIO_NONE && (CDI = ConDesGetImport (I)) != 0) { unsigned J; /* Generate a new import, and add it to the module's import list. */ Import* Imp = GenImport (CDI->Name, CDI->AddrSize); Imp->Obj = O; CollAppend (&O->Imports, Imp); /* Add line info for the export that is actually the condes that ** forces the import. Then, add line info for the config. file. ** The export's info is added first because the import pretends ** that it came from the object module instead of the config. file. */ for (J = 0; J < CollCount (&E->DefLines); ++J) { CollAppend (&Imp->RefLines, DupLineInfo (CollAt (&E->DefLines, J))); } CollAppend (&Imp->RefLines, GenLineInfo (&CDI->Pos)); } } /* Return the new export */ return E; }