/* * Copyright 2011 Steven Gribble * * This file is part of the UW CSE 333 course project sequence * (333proj). * * 333proj is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 333proj is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 333proj. If not, see . */ #include #include #include #include #include #include "ll_file.h" #include "ll_priv.h" int WriteToFile(LinkedList list, char *filename, PayloadToByteArrayFnPtr f) { FILE *outf = NULL; LLIter it = NULL; // Open up the file. outf = fopen(filename, "wb+"); if (f == NULL) return 0; // Test a corner case. if (NumElementsInLinkedList(list) == 0) goto done; // Prepare our iterator. it = LinkedListMakeIterator(list, 0); if (it == NULL) { fclose(outf); unlink(filename); return 0; } // Loop through the list items. while (1) { // Get the byte array. void *payload; unsigned char *arr = NULL; uint32_t arrlen, outlen; // get the list item payload. assert(LLIteratorGetPayload(it, &payload) == 1); // convert the list item payload to a writable byte array. arr = (unsigned char *) f(payload, &arrlen); assert(arrlen > 0); // write a record, with len in network order. a record // is a network order 32 bit int representing the payload // length, followed by the payload bytes. outlen = htonl(arrlen); assert(fwrite(&outlen, 1, sizeof(uint32_t), outf) == sizeof(uint32_t)); assert(fwrite(arr, 1, arrlen, outf) == arrlen); // free the writable byte array. free(arr); // go to the next item in the list and loop around. if (LLIteratorNext(it) == 0) goto done; } done: // All done; clean up and return. if (f != NULL) fclose(outf); if (it != NULL) LLIteratorFree(it); return 1; } LinkedList ReadFromFile(char *filename, ByteArrayToPayloadFnPtr f) { FILE *inf = NULL; LinkedList list = NULL; // Open up the file. inf = fopen(filename, "rb"); if (inf == NULL) goto done; // Create the list. list = AllocateLinkedList(); if (list == NULL) goto done; // Loop through the file. while (1) { uint32_t nextlen; unsigned char *buf; void *payload; // Read the length, convert from network to host order. if (fread(&nextlen, 1, sizeof(uint32_t), inf) != sizeof(uint32_t)) { goto done; } nextlen = ntohl(nextlen); // Allocate a buffer for the next record, read it in. buf = (unsigned char *) malloc(nextlen * sizeof(char)); assert(buf != NULL); assert(fread(buf, 1, nextlen, inf) == nextlen); // Great! Convert the payload, add it in. payload = f(buf, sizeof(uint32_t)); assert(AppendLinkedList(list, payload) == 1); // Free the buf we read in, loop around. free(buf); } done: // All done! Clean up and return the list. if (inf != NULL) fclose(inf); return list; }