#include "fifo.h" #if _WIN32 | _WIN64 #include #include #else #include // hah #endif #include // remove() #include // uint32_t #include #include #include // scandir #include // stat #include // access() #include "string.h" #include /* ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, Data Serialization, etc. ```````````````````````````````` Newsboy uses a mock-XDR style data xfer syntax. All data types are at least 32 bits long (4 bytes) and must always be a multiple of four. If the number of bytes in the data to be written is not a multiple of four, then additional padding is added. */ char *type_name[] = { "char", "int", "float", "string", "magic" }; int getType(const char *name) { int i; for (i = 0; i < 5; i++) { if (strcmp(name, type_name[i]) == 0) { return i; } } return T_INT; // return int default } char *getTypeName(int type) { if (type < 0 || type >= T_COUNT) return NULL; return type_name[type]; } void *readData(FILE *input, int type, void *storage) { uint32_t val; int i = 0; switch (type) { case T_MAGIC: fread(&val, sizeof(char)*4, 1, input); //storage = realloc(storage, sizeof(char)*4); memcpy(storage, &val, sizeof(char)*4); break; case T_CHAR: fread(&val, sizeof(char)*4, 1, input); val = ntohl(val); //storage = realloc(storage, sizeof(char)*4); memcpy(storage, &val, sizeof(char)); break; case T_FLOAT: fread(&val, sizeof(char)*4, 1, input); val = ntohf((float)val); //storage = realloc(storage, sizeof(char)*4); memcpy(storage, &val, sizeof(char)*4); break; case T_INT: fread(&val, sizeof(char)*4, 1, input); val = ntohl(val); //storage = realloc(storage, sizeof(char)*4); memcpy(storage, &val, sizeof(char)*4); break; case T_STRING: // get length fread(&val, sizeof(char)*4, 1, input); val = ntohl(val); // allocate passed storage to new size storage = realloc(storage, sizeof(char)*val); // get chunk count int chunk = val / sizeof(char)*4; // chunk count int ch; // chunk char offset int offset = 0; // storage offset // copy chunks to storage for (i = 0; i < chunk; i++) { // read chunk into val fread(&val, sizeof(char), 4, input); // read this chunk char by char into storage for (ch = 0; ch < 4; ch++) { ((char *)storage)[offset++] = ((char*)&val)[ch]; if (((char *)&val)[ch] == '\0') { chunk = 0; ch = 4; } } //memcpy(&((char*)storage)[0], (char*)&val, sizeof(char)*4); } break; } return storage; } int writeData(FILE *output, int type, void *data) { uint32_t val; int i; switch (type) { case T_MAGIC: val = *(int*)data; fwrite(&val, sizeof(char)*4, 1, output); break; case T_CHAR: val = htonl(*(int*)(char*)data); fwrite(&val, sizeof(char)*4, 1, output); break; case T_INT: val = htonl(*(int*)data); fwrite(&val, sizeof(char)*4, 1, output); break; case T_FLOAT: // WROOOONG {} float fl = *(float*)data; val = htonf(fl); //val = *(float*)data; fwrite(&fl, sizeof(char)*4, 1, output); break; case T_STRING: i = strlen(*(char **)data)+1; // write size, including \0 val = htonl(i); fwrite(&val, sizeof(char)*4, 1, output); int offset = 0; int ch = 0; int chunk = i / sizeof(char)*4; for (i = 0; i < chunk; i++) { val = 0; // clear out last chunk ch = 0; // reset position while (ch < 4) { ((char *)&val)[ch++] = (*(char**)data)[offset++]; if ((*(char**)data)[offset-1] == '\0') { chunk = 0; ch = 4; } } fwrite(&val, sizeof(char)*4, 1, output); } break; } return 0; } struct Dir *openDir(const char *path, int order) { if (path == NULL) return NULL; struct Dir *dir = malloc(sizeof(struct Dir)); if (dir == NULL) { printf("malloc failed\n"); return NULL; } dir->current = NULL; dir->start = NULL; dir->order = order; int size = strlen(path)+2; // +2 to add trailed '/' for winderps dir->dirname = malloc(size+1); memcpy(dir->dirname, path, size); dir->dirname[size-2] = '/'; // hi, winderps dir->dirname[size-1] = '\0'; #if _WIN32 | _WIN64 WIN32_FIND_DATA ffd; HANDLE h_find = INVALID_HANDLE_VALUE; char crappy_windows_dir[MAX_PATH]; StringCbCopyN(crappy_windows_dir, MAX_PATH, dir->dirname, size); StringCbCatN(crappy_windows_dir, MAX_PATH, "*", 2); h_find = FindFirstFile(crappy_windows_dir, &ffd); if (h_find == INVALID_HANDLE_VALUE) { // some sort of rubbish windows error } struct DirEntry *last_entry = NULL; do { struct DirEntry *entry = malloc(sizeof(struct DirEntry)); // copy over filename int new_size = strlen(ffd.cFileName)+1; entry->d_name = malloc(new_size); memcpy(entry->d_name, ffd.cFileName, new_size); // NULL it! entry->next = NULL; if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { entry->d_type = F_DIR; } else { entry->d_type = F_REG; } // initial linked list if not yet done if (dir->start == NULL) { dir->start = entry; dir->current = entry; } // assign this entry to last_entry's next if possible if (last_entry != NULL) { last_entry->next = entry; } // set this entry to last entry last_entry = entry; } while (FindNextFile(h_find, &ffd)); FindClose(h_find); #else struct dirent **files; int n; n = scandir(dir->dirname, &files, NULL, alphasort); if (n < 0) { perror("openDir"); return NULL; } else { struct DirEntry *last_entry = NULL; int i; for(i = 0; i < n; i++) { struct DirEntry *entry = malloc(sizeof(struct DirEntry)); // copy over filename entry->d_name = malloc(1); entry->d_name = copyString(entry->d_name, files[i]->d_name); // NULL it! entry->next = NULL; // build full path name int dir_length = strlen(dir->dirname); int file_length = strlen(files[i]->d_name); char filepath[dir_length+file_length+2]; memcpy(filepath, dir->dirname, dir_length); filepath[dir_length] = '/'; memcpy(filepath+dir_length+1, files[i]->d_name, file_length+1); // get file info struct stat file_stat; stat(filepath, &file_stat); switch(file_stat.st_mode & S_IFMT) { case S_IFDIR: entry->d_type = F_DIR; break; case S_IFREG: entry->d_type = F_REG; break; case S_IFLNK: entry->d_type = F_LNK; break; default: entry->d_type = F_UKN; break; } // initial linked list if not yet done if (dir->start == NULL) { dir->start = entry; dir->current = entry; } // assign this entry to last_entry's next if possible if (last_entry != NULL) { last_entry->next = entry; } // set this entry to last entry last_entry = entry; free(files[i]); } free(files); } #endif return dir; } int closeDir(struct Dir *dir) { if (dir == NULL) return 1; struct DirEntry *entry = dir->start; while(entry != NULL) { struct DirEntry *last_entry = entry; entry = entry->next; free(last_entry->d_name); free(last_entry); } free(dir->dirname); free(dir); return 0; } struct DirEntry *readDir(struct Dir *dir) { if (dir == NULL) return NULL; if (dir->current == NULL) return NULL; struct DirEntry *entry = dir->current; dir->current = entry->next; return entry; } int fileExists(const char *filename) { if (access(filename, F_OK) == 0) { return 1; } return 0; } int deleteFile(const char *filename) { if (filename == NULL) return 1; if (!fileExists(filename)) { return 2; } return remove(filename); } int fileToBuffer(char **buffer, const char *filename) { int i, n, pos = 0; char t_buf[16]; FILE *file = fopen(filename, "r"); if (file == NULL) { return -1; } // get file size for realloc() and future return fseek(file, 0, SEEK_END); int size = ftell(file)+1; fseek(file, 0, SEEK_SET); *buffer = realloc(*buffer, size); while ((n = fread(t_buf, 1, 16, file))) { for (i = 0; i < n; i++) { (*buffer)[pos++] = t_buf[i]; } } (*buffer)[size-1] = '\0'; fclose(file); return size; } int hasExtension(const char *name, const char *extension) { if (name == NULL || extension == NULL) return 0; char *exten; if ((exten = strrchr(name, '.')) == NULL) { return 0; } if (strcmp(exten, extension) != 0) { return 0; } return 1; } // hah, this doesn't really remove it, but w/e char *remExtension(char *name, const char *extension) { if (name == NULL || extension == NULL) return 0; char *exten; if ((exten = strrchr(name, '.')) == NULL) { return name; } if (strcmp(exten, extension) != 0) { return name; } *exten = '\0'; return name; } float htonf(float fl) { uint32_t swap = htonl(*(int*)&fl); return *(float *)&swap; } float ntohf(float fl) { uint32_t swap = ntohl(*(int*)&fl); return *(float *)&swap; }