int GFFFile::finalWriteExoStr(std::string &exostr, uint32 &ofieldd) { if(binWrite((uint32) (ofieldd-offfielddata))) return errcode; if(seek(ofieldd)) return errcode; if(binWrite((uint32) exostr.size())) return errcode; if(rawWrite((char*) exostr.c_str(), exostr.size())) return errcode; // Overflow check, if that fires, something really bad happened if((ofieldd += exostr.size()+4) > offfieldidx) return errcode = 23; return errcode = 0; }
int GFFFile::finalWriteResRef(std::string &resref, uint32 &ofieldd) { if(binWrite((uint32) (ofieldd-offfielddata))) return errcode; if(seek(ofieldd)) return errcode; if(binWrite((uint8) resref.size())) return errcode; if(rawWrite((char*) resref.c_str(), resref.size())) return errcode; // Overflow check, if that fires, something really bad happened if((ofieldd += resref.size()+1) > offfieldidx) return errcode = 23; return errcode = 0; }
int GFFFile::finalWriteData(void) { if(seek(offfielddata)) return errcode; for(uint32 i=0;i<datas.size();i++) { if(binWrite(datasizes[i])) return errcode; if(binWrite(datas[i], datasizes[i])) return errcode; // offfielddata += datasizes[i] + 4; } return errcode = 0; }
int GFFFile::finalWriteLists(void) { if(seek(offlistidx)) return errcode; for(uint32 i=0;i<lists.size();i++) { listoffs.push_back(tell()-offlistidx); if(binWrite((uint32) lists[i].size())) return errcode; for(uint32 j=0;j<lists[i].size();j++) if(binWrite(lists[i][j])) return errcode; } return errcode = 0; }
void compressFile(FILE* outFp, FILE* inpFp) { LZ4_stream_t lz4Stream_body; LZ4_stream_t* lz4Stream = &lz4Stream_body; char inpBuf[2][BLOCK_BYTES]; int inpBufIndex = 0; LZ4_resetStream(lz4Stream); while(1) { char* const inpPtr = inpBuf[inpBufIndex]; const int inpBytes = (int) binRead(inpFp, inpPtr, BLOCK_BYTES); if (0 == inpBytes) { break; } { char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)]; const int cmpBytes = LZ4_compress_fast_continue(lz4Stream, inpPtr, cmpBuf, inpBytes, sizeof(cmpBuf), 1); if(cmpBytes <= 0) { break; } intWrite(outFp, cmpBytes); binWrite(outFp, cmpBuf, (size_t) cmpBytes); } inpBufIndex = (inpBufIndex + 1) % 2; } intWrite(outFp, 0); }
int SSFFile::finalWriteEntries(void) { if(offsets.empty()) return errcode = 25; if(seek(offtable)) return errcode; for(uint32 i=0;i<entrycount;i++) if(binWrite((uint32) (offsets[0] + i*20))) return errcode; return errcode = 0; }
int SSFFile::finalWriteData(void) { uint32 l; if(offsets.empty()) return errcode = 25; if(seek(offsets[0])) return errcode; for(uint32 i=0;i<entrycount;i++) { // ResRefs have to have at most 16 characters if(resrefs[i].length() > 16) resrefs[i].erase(16); if(rawWrite((char*) resrefs[i].c_str(), l=resrefs[i].length())) return errcode; // Pad to a total of 16 bytes for(l=l;l<16;l++) if(binWrite((uint8) 0)) return errcode; if(binWrite(stringrefs[i])) return errcode; } return errcode = 0; }
int SSFFile::finalWriteHeader(void) { char *magic; if(seek(0)) return errcode; if(!(magic = (char*) getFileMagicByResType(type))) return errcode = 11; if(rawWrite(magic, 4)) return errcode; if(rawWrite("V1.0", 4)) return errcode; if(binWrite(2, entrycount, offtable)) return errcode; return errcode = 0; }
int TLKFile::finalWriteHeader(void) { char *magic; if(seek(0)) return errcode; if(!(magic = (char*) getFileMagicByResType(type))) return errcode = 11; if(rawWrite(magic, 4)) return errcode; if(rawWrite("V3.0", 4)) return errcode; if(binWrite(3, (uint32) language, strcount, offstrings)) return errcode; return errcode = 0; }
int GFFFile::finalWriteExoLocStr(ExoLocString &exolocstr, uint32 &ofieldd) { uint32 size=0, count=0; if(binWrite((uint32) (ofieldd-offfielddata))) return errcode; if(seek(ofieldd+12)) return errcode; for(uint32 i=0;i<NWN_LANG_MAX;i++) if(!exolocstr.str[i].empty()) { if(binWrite(2, i, (uint32) exolocstr.str[i].size())) return errcode; if(rawWrite((char*) exolocstr.str[i].c_str(), exolocstr.str[i].size())) return errcode; count++; size += exolocstr.str[i].size()+8; } if(seek(ofieldd)) return errcode; if(binWrite(3, (uint32) size+8, exolocstr.stringref, count)) return errcode; // Overflow check, if that fires, something really bad happened if((ofieldd += size+12) > offfieldidx) return errcode = 23; return errcode = 0; }
int GFFFile::finalWriteLabels(void) { int l; if(seek(offlabel)) return errcode; for(uint32 i=0;i<labels.size();i++) { if(rawWrite(labels[i].c_str(), l=labels[i].length())) return errcode; // Pad to a total of 16 bytes for(l=l;l<16;l++) if(binWrite((uint8) 0)) return errcode; } return errcode = 0; }
int ERFFile::finalWriteKeyList(void) { int l; if(seek(offkeylist)) return errcode; for(uint32 i=0;i<entrycount;i++) { // ResRefs have to have at most 16 characters if(resrefs[i].length() > 16) resrefs[i].erase(16); lowerStr(resrefs[i]); if(rawWrite((char*) resrefs[i].c_str(), l=resrefs[i].length())) return errcode; // Pad to a total of 16 bytes for(l=l;l<16;l++) if(binWrite((uint8) 0)) return errcode; if(binWrite(i)) return errcode; if(binWrite((uint16) restypes[i])) return errcode; if(binWrite((uint16) 0)) return errcode; // Overflow check, if that fires, something really bad happened if(tell() > offreslist) return errcode = 23; } return errcode = 0; }
int ERFFile::finalWriteHeader(void) { char *magic; if(seek(0)) return errcode; if(!(magic = (char*) getFileMagicByResType(type))) return errcode = 11; if(rawWrite(magic, 4)) return errcode; if(rawWrite("V1.0", 4)) return errcode; if(binWrite(9, langcount, locstrsize, entrycount, offlocstr, offkeylist, offreslist, buildyear, buildday, desc.stringref)) return errcode; return errcode = 0; }
int GFFFile::finalWriteHeader(void) { char *magic; if(seek(0)) return errcode; if(!(magic = (char*) getFileMagicByResType(type))) return errcode = 11; if(rawWrite(magic, 4)) return errcode; if(rawWrite("V3.2", 4)) return errcode; if(binWrite(12, offstruct, structcount, offfield, fieldcount, offlabel, labelcount, offfielddata, fielddatasize, offfieldidx, fieldidxsize, offlistidx, listidxsize)) return errcode; return errcode = 0; }
int ERFFile::finalWriteDescription(void) { if(seek(offlocstr)) return errcode; for(uint32 i=0;i<NWN_LANG_MAX;i++) if(!desc.str[i].empty()) { if(binWrite(2, i, (uint32) desc.str[i].length())) return errcode; if(rawWrite((char*) desc.str[i].c_str(), desc.str[i].size())) return errcode; } // Overflow check, if that fires, something really bad happened if(tell() > offkeylist) return errcode = 23; return errcode = 0; }
int TLKFile::finalWriteTable(void) { uint32 l; if(seek(20)) return errcode; offsets.resize(1); offsets[0] = 0; for(uint32 i=0;i<strcount;i++) { if(binWrite((uint32) flags[i])) return errcode; // ResRefs have to have at most 16 characters if(sndresrefs[i].length() > 16) sndresrefs[i].erase(16); if(rawWrite((char*) sndresrefs[i].c_str(), l=sndresrefs[i].length())) return errcode; // Pad to a total of 16 bytes for(l=l;l<16;l++) if(binWrite((uint8) 0)) return errcode; if(binWrite(2, (uint32) 0, (uint32) 0)) return errcode; if(binWrite(2, offsets[0], (uint32) strings[i].length())) return errcode; if(binWrite(sndlengths[i])) return errcode; offsets[0] += strings[i].length(); } return errcode = 0; }
int GFFFile::finalWriteStructs(void) { uint32 ostruct=offstruct, ofield=offfield; uint32 ofieldd=offfielddata+datasize, ofieldi=offfieldidx; uint32 nfield=0; if(seek(ostruct)) return errcode; for(uint32 i=0;i<structs.size();i++) { if(binWrite(structs[i].id)) return errcode; if(structs[i].fieldcount == 1) { if(binWrite(nfield++)) return errcode; if(seek(ofield)) return errcode; if(finalWriteField(i, 0, ofield, ofieldd)) return errcode; } else { if(binWrite((uint32) (ofieldi-offfieldidx))) return errcode; for(uint32 j=0;j<structs[i].fieldcount;j++) { if(seek(ofield)) return errcode; if(finalWriteField(i, j, ofield, ofieldd)) return errcode; if(seek(ofieldi)) return errcode; if(binWrite(nfield++)) return errcode; // Overflow check, if that fires, something really bad happened if((ofieldi += 4) > offlistidx) return errcode = 23; } } if(seek(ostruct+8)) return errcode; if(binWrite(structs[i].fieldcount)); // Overflow check, if that fires, something really bad happened if((ostruct += 12) > offfield) return errcode = 23; } return errcode = 0; }
int ERFFile::finalWriteResList(void) { if(seek(offreslist)) return errcode; if(offsets.empty()) return errcode = 25; offsets.resize(2); offsets[1] = offsets[0]; for(uint32 i=0;i<entrycount;i++) { if(binWrite(2, offsets[1], sizes[i])) return errcode; offsets[1] += sizes[i]; // Overflow check, if that fires, something really bad happened if(tell() > offsets[0]) return errcode = 23; } return errcode = 0; }
void decompressFile(FILE* outFp, FILE* inpFp) { LZ4_streamDecode_t lz4StreamDecode_body; LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body; char decBuf[2][BLOCK_BYTES]; int decBufIndex = 0; LZ4_setStreamDecode(lz4StreamDecode, NULL, 0); while(1) { char cmpBuf[LZ4_COMPRESSBOUND(BLOCK_BYTES)]; int cmpBytes = 0; { const size_t readCount0 = intRead(inpFp, &cmpBytes); if((readCount0 != 1) || (cmpBytes <= 0)) { break; } const size_t readCount1 = binRead(inpFp, cmpBuf, (size_t) cmpBytes); if(readCount1 != (size_t) cmpBytes) { break; } } { char* const decPtr = decBuf[decBufIndex]; const int decBytes = LZ4_decompress_safe_continue(lz4StreamDecode, cmpBuf, decPtr, cmpBytes, BLOCK_BYTES); if(decBytes <= 0) { break; } binWrite(outFp, decPtr, (size_t) decBytes); } decBufIndex = (decBufIndex + 1) % 2; } }
int GFFFile::finalWriteField(uint32 sct, uint32 f, uint32 &ofield, uint32 &ofieldd) { NWNVarType &type = structs[sct].types[f]; if(binWrite(2, (uint32) type, (uint32) ((uint64) structs[sct].labels[f]))) return errcode; switch(type) { case NWN_VAR_UINT64: case NWN_VAR_INT64: case NWN_VAR_FLOAT64: if(binWrite((uint32) (ofieldd-offfielddata))) return errcode; if(seek(ofieldd)) return errcode; if(binWrite((uint64) structs[sct].values[f])) return errcode; // Overflow check, if that fires, something really bad happened if((ofieldd += 8) > offfieldidx) return errcode = 23; break; case NWN_VAR_RESREF: if(finalWriteResRef(resrefs[structs[sct].values[f]], ofieldd)) return errcode; break; case NWN_VAR_EXOSTR: if(finalWriteExoStr(exostrs[structs[sct].values[f]], ofieldd)) return errcode; break; case NWN_VAR_EXOLOCSTR: if(finalWriteExoLocStr(exolocstrs[structs[sct].values[f]], ofieldd)) return errcode; break; case NWN_VAR_VOID: if(structs[sct].values[f] >= dataoffs.size()) return errcode = 13; if(binWrite(dataoffs[structs[sct].values[f]])) return errcode; break; case NWN_VAR_LIST: if(structs[sct].values[f] >= lists.size()) return errcode = 22; if(binWrite(listoffs[structs[sct].values[f]])) return errcode; break; default: if(binWrite((uint32) structs[sct].values[f])) return errcode; break; } // Overflow check, if that fires, something really bad happened if((ofield += 12) > offlabel) return errcode = 23; if(seek(ofield)) return errcode; return errcode = 0; }