Commit 36186f24506bab878dc39553217da0e030e81867

Authored by Imanol-Mikel Barba Sabariego
1 parent 6bafc25c

Added compose functions. Fixed compression error caused by clobbering headerless…

… zlib data. Minor fixes.
@@ -32,7 +32,7 @@ int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, siz @@ -32,7 +32,7 @@ int overwriteChunk(const char* regionFolder, ChunkID chunk, void* chunkData, siz
32 relativeChunk.z = chunk.z % 32; 32 relativeChunk.z = chunk.z % 32;
33 33
34 char* regionFilename = calloc(MAX_REGION_FILENAME_LENGTH + strlen(regionFolder),sizeof(char)); 34 char* regionFilename = calloc(MAX_REGION_FILENAME_LENGTH + strlen(regionFolder),sizeof(char));
35 - sprintf(regionFilename,"%s/r.%d.%d.mca.new",regionFolder,region.x,region.z); 35 + sprintf(regionFilename,"%s/r.%d.%d.mca",regionFolder,region.x,region.z);
36 36
37 if(access(regionFilename,R_OK | W_OK) == -1) { 37 if(access(regionFilename,R_OK | W_OK) == -1) {
38 fprintf(stderr,"Can't access file %s: %s\n",regionFilename,strerror(errno)); 38 fprintf(stderr,"Can't access file %s: %s\n",regionFilename,strerror(errno));
compression.c
@@ -125,8 +125,10 @@ ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int @@ -125,8 +125,10 @@ ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData, int
125 return -4; 125 return -4;
126 } 126 }
127 127
128 - // Set OS Flag to 0x00: "FAT filesystem (MS-DOS, OS/2, NT/Win32)"  
129 - comp[OS_FLAG_OFFSET] = 0x00; 128 + if(!headerless) {
  129 + // Set OS Flag to 0x00: "FAT filesystem (MS-DOS, OS/2, NT/Win32)"
  130 + comp[OS_FLAG_OFFSET] = 0x00;
  131 + }
130 132
131 *compData = comp; 133 *compData = comp;
132 return compLength; 134 return compLength;
@@ -11,6 +11,10 @@ unsigned int parseList(void* addr, TagList* tl, uint8_t type); @@ -11,6 +11,10 @@ unsigned int parseList(void* addr, TagList* tl, uint8_t type);
11 unsigned int parseCompound(void* addr, TagCompound* tc); 11 unsigned int parseCompound(void* addr, TagCompound* tc);
12 unsigned int parsePayload(void* addr,Tag* t); 12 unsigned int parsePayload(void* addr,Tag* t);
13 unsigned int parseTag(void* addr, Tag* t); 13 unsigned int parseTag(void* addr, Tag* t);
  14 +size_t composeCompound(TagCompound* tc, void** data);
  15 +size_t composeList(uint8_t listType, TagList* tl, void** data);
  16 +size_t composePayload(Tag t, void** data);
  17 +size_t composeTag(Tag t, void** data);
14 18
15 ssize_t loadDB(const char* filename, void** data) { 19 ssize_t loadDB(const char* filename, void** data) {
16 if(access(filename,R_OK) == -1) { 20 if(access(filename,R_OK) == -1) {
@@ -246,4 +250,145 @@ unsigned int parseTag(void* addr, Tag* t) { @@ -246,4 +250,145 @@ unsigned int parseTag(void* addr, Tag* t) {
246 pos += parsePayload(pos,t); 250 pos += parsePayload(pos,t);
247 251
248 return pos-addr; 252 return pos-addr;
  253 +}
  254 +
  255 +size_t composeCompound(TagCompound* tc, void** data) {
  256 + size_t totalPayloadLength = 0;
  257 + void* totalPayload = calloc(1,sizeof(char));
  258 + unsigned int pos = 0;
  259 + size_t childTagPayloadLength = 0;
  260 + void* childTagPayload;
  261 + for(int i = 0; i < tc->numTags; ++i) {
  262 + childTagPayloadLength = composeTag(tc->list[i],&childTagPayload);
  263 + totalPayloadLength += childTagPayloadLength;
  264 + void* newptr = realloc(totalPayload,totalPayloadLength);
  265 + if(newptr == NULL) {
  266 + fprintf(stderr, "Unable to realloc memory for child tag\n");
  267 + free(totalPayload);
  268 + free(childTagPayload);
  269 + return 0;
  270 + }
  271 + totalPayload = newptr;
  272 + memcpy(totalPayload+pos,childTagPayload,childTagPayloadLength);
  273 + free(childTagPayload);
  274 + pos += childTagPayloadLength;
  275 + }
  276 + void* newptr = realloc(totalPayload,++totalPayloadLength);
  277 + if(newptr == NULL) {
  278 + fprintf(stderr, "Unable to realloc memory for end tag\n");
  279 + free(totalPayload);
  280 + return 0;
  281 + }
  282 + totalPayload = newptr;
  283 + ((uint8_t*)totalPayload)[pos] = 0x00;
  284 + *data = totalPayload;
  285 + return totalPayloadLength;
  286 +}
  287 +
  288 +size_t composeList(uint8_t listType, TagList* tl, void** data) {
  289 + size_t totalPayloadLength = 0;
  290 + if(listType == TAG_LIST) {
  291 + totalPayloadLength += sizeof(uint8_t);
  292 + }
  293 + void* totalPayload = calloc(totalPayloadLength + sizeof(uint32_t),sizeof(char));
  294 + if(listType == TAG_LIST) {
  295 + ((uint8_t*)totalPayload)[0] = tl->type;
  296 + }
  297 + uint32_t u32 = __bswap_32(tl->size);
  298 + memcpy((uint8_t*)totalPayload + totalPayloadLength,&u32,sizeof(uint32_t));
  299 + totalPayloadLength += sizeof(uint32_t);
  300 +
  301 + unsigned int pos = totalPayloadLength;
  302 + size_t childTagPayloadLength = 0;
  303 + void* childTagPayload;
  304 + for(int i = 0; i < tl->size; ++i) {
  305 + childTagPayloadLength = composePayload(tl->list[i],&childTagPayload);
  306 + totalPayloadLength += childTagPayloadLength;
  307 + void* newptr = realloc(totalPayload,totalPayloadLength);
  308 + if(newptr == NULL) {
  309 + fprintf(stderr, "Unable to realloc memory for child tag\n");
  310 + free(totalPayload);
  311 + free(childTagPayload);
  312 + return 0;
  313 + }
  314 + totalPayload = newptr;
  315 + memcpy(totalPayload+pos,childTagPayload,childTagPayloadLength);
  316 + free(childTagPayload);
  317 + pos += childTagPayloadLength;
  318 + }
  319 +
  320 + *data = totalPayload;
  321 + return totalPayloadLength;
  322 +}
  323 +
  324 +size_t composePayload(Tag t, void** data) {
  325 + size_t payloadLength = getTypeSize(t.type); // initially, then particularly for lists/compounds/strings
  326 + void* payload;
  327 +
  328 + uint16_t u16 = 0;
  329 + uint32_t u32 = 0;
  330 + uint64_t u64 = 0;
  331 + switch(t.type) {
  332 + case TAG_BYTE:
  333 + payload = calloc(1,payloadLength);
  334 + memcpy(payload,t.payload,t.payloadLength);
  335 + break;
  336 + case TAG_SHORT:
  337 + u16 = __bswap_16(*(uint16_t*)t.payload);
  338 + payload = calloc(1,payloadLength);
  339 + memcpy(payload,&u16,t.payloadLength);
  340 + break;
  341 + case TAG_INT:
  342 + case TAG_FLOAT:
  343 + u32 = __bswap_32(*(uint32_t*)t.payload);
  344 + payload = calloc(1,payloadLength);
  345 + memcpy(payload,&u32,t.payloadLength);
  346 + break;
  347 + case TAG_LONG:
  348 + case TAG_DOUBLE:
  349 + u64 = __bswap_64(*(uint64_t*)t.payload);
  350 + payload = calloc(1,payloadLength);
  351 + memcpy(payload,&u64,t.payloadLength);
  352 + break;
  353 + case TAG_STRING:
  354 + payloadLength = sizeof(uint16_t) + t.payloadLength;
  355 + payload = calloc(payloadLength,sizeof(char));
  356 + u16 = __bswap_16((uint16_t)t.payloadLength);
  357 + memcpy(payload,&u16,sizeof(uint16_t));
  358 + memcpy(payload + sizeof(uint16_t),t.payload,t.payloadLength);
  359 + break;
  360 + case TAG_COMPOUND:
  361 + payloadLength = composeCompound((TagCompound*)t.payload,&payload);
  362 + break;
  363 + case TAG_LIST:
  364 + case TAG_BYTEARRAY:
  365 + case TAG_INTARRAY:
  366 + payloadLength = composeList(t.type,(TagList*)t.payload,&payload);
  367 + break;
  368 + }
  369 +
  370 + *data = payload;
  371 + return payloadLength;
  372 +}
  373 +
  374 +size_t composeTag(Tag t, void** data) {
  375 + size_t headerSize = sizeof(uint8_t) + sizeof(uint16_t) + t.nameLength;
  376 + void* tagHeader = calloc(headerSize,sizeof(char));
  377 + ((uint8_t*)tagHeader)[0] = t.type;
  378 + uint16_t u16 = __bswap_16(t.nameLength);
  379 + memcpy(tagHeader+sizeof(uint8_t),&u16,sizeof(uint16_t));
  380 + memcpy(tagHeader+sizeof(uint8_t) + sizeof(uint16_t), t.name, t.nameLength);
  381 + void* tagPayload;
  382 + size_t payloadSize = composePayload(t,&tagPayload);
  383 + void* tagData = realloc(tagHeader,headerSize + payloadSize);
  384 + if(tagData == NULL) {
  385 + fprintf(stderr, "Unable to realloc memory to merge header and payload\n");
  386 + free(tagHeader);
  387 + free(tagPayload);
  388 + return 0;
  389 + }
  390 + memcpy(tagData + headerSize,tagPayload, payloadSize);
  391 + free(tagPayload);
  392 + *data = tagData;
  393 + return headerSize + payloadSize;
249 } 394 }
250 \ No newline at end of file 395 \ No newline at end of file
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 typedef struct Tag { 26 typedef struct Tag {
27 uint8_t type; 27 uint8_t type;
28 char* name; 28 char* name;
29 - unsigned int nameLength; 29 + uint16_t nameLength;
30 unsigned int payloadLength; 30 unsigned int payloadLength;
31 void* payload; 31 void* payload;
32 } Tag; 32 } Tag;
@@ -60,5 +60,6 @@ enum TAG { @@ -60,5 +60,6 @@ enum TAG {
60 ssize_t loadDB(const char* filename, void** data); 60 ssize_t loadDB(const char* filename, void** data);
61 void destroyTag(Tag* t); 61 void destroyTag(Tag* t);
62 unsigned int parseTag(void* addr, Tag* t); 62 unsigned int parseTag(void* addr, Tag* t);
  63 +size_t composeTag(Tag t, void** data);
63 64
64 #endif 65 #endif
65 \ No newline at end of file 66 \ No newline at end of file