diff options
author | Michele Papalini <micpapal+fdio@cisco.com> | 2017-02-24 08:00:33 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2017-02-24 08:00:33 +0000 |
commit | 4df7f4cc98b6288177df256e1db70ddc3f7d00db (patch) | |
tree | 55e71277b419e4830ae641868ab8e751c8b86972 /libparc/parc/algol/parc_RandomAccessFile.c | |
parent | f28308bd99381ef5f1e178e2e1f870f245e35873 (diff) | |
parent | ec688b4723a041044226358bcd4dd6e2da39da49 (diff) |
Merge "Initial commit: cframework. Longbow and Libparc" into cframework/master
Diffstat (limited to 'libparc/parc/algol/parc_RandomAccessFile.c')
-rwxr-xr-x | libparc/parc/algol/parc_RandomAccessFile.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/libparc/parc/algol/parc_RandomAccessFile.c b/libparc/parc/algol/parc_RandomAccessFile.c new file mode 100755 index 00000000..65bff1d1 --- /dev/null +++ b/libparc/parc/algol/parc_RandomAccessFile.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ +#include <config.h> + +#include <parc/algol/parc_Object.h> +#include <parc/algol/parc_DisplayIndented.h> +#include <parc/algol/parc_Memory.h> + +#include <parc/algol/parc_RandomAccessFile.h> + +#include <stdio.h> + +struct PARCRandomAccessFile { + char *fname; + FILE *fhandle; +}; + +static void +_parcRandomAccessFile_Finalize(PARCRandomAccessFile **instancePtr) +{ + assertNotNull(instancePtr, "Parameter must be a non-null pointer to a PARCRandomAccessFile pointer."); + PARCRandomAccessFile *instance = *instancePtr; + if (instance->fhandle != NULL) { + fclose(instance->fhandle); + } + if (instance->fname != NULL) { + parcMemory_Deallocate(&instance->fname); + } +} + +parcObject_ImplementAcquire(parcRandomAccessFile, PARCRandomAccessFile); + +parcObject_ImplementRelease(parcRandomAccessFile, PARCRandomAccessFile); + +parcObject_ExtendPARCObject(PARCRandomAccessFile, _parcRandomAccessFile_Finalize, NULL, + parcRandomAccessFile_ToString, parcRandomAccessFile_Equals, NULL, + parcRandomAccessFile_HashCode, parcRandomAccessFile_ToJSON); + + +void +parcRandomAccessFile_AssertValid(const PARCRandomAccessFile *instance) +{ + assertTrue(parcRandomAccessFile_IsValid(instance), + "PARCRandomAccessFile is not valid."); +} + +void +parcRandomAccessFile_Display(const PARCRandomAccessFile *instance, int indentation) +{ + parcDisplayIndented_PrintLine(indentation, "PARCRandomAccessFile@%p {", instance); + parcDisplayIndented_PrintLine(indentation + 1, "File: %s", instance->fname); + parcDisplayIndented_PrintLine(indentation, "}"); +} + +PARCHashCode +parcRandomAccessFile_HashCode(const PARCRandomAccessFile *instance) +{ + return parcHashCode_Hash((uint8_t *) instance->fname, strlen(instance->fname)); +} + +bool +parcRandomAccessFile_Equals(const PARCRandomAccessFile *x, const PARCRandomAccessFile *y) +{ + bool result = false; + + if (x == y) { + result = true; + } else if (x == NULL || y == NULL) { + result = false; + } else { + if (strcmp(x->fname, y->fname) == 0) { + result = true; + } + } + + return result; +} + +bool +parcRandomAccessFile_IsValid(const PARCRandomAccessFile *instance) +{ + bool result = false; + + if (instance != NULL) { + result = instance->fhandle != NULL; + } + + return result; +} + +PARCJSON * +parcRandomAccessFile_ToJSON(const PARCRandomAccessFile *instance) +{ + PARCJSON *result = parcJSON_Create(); + + if (result != NULL) { + parcJSON_AddString(result, "fname", instance->fname); + } + + return result; +} + +char * +parcRandomAccessFile_ToString(const PARCRandomAccessFile *instance) +{ + char *result = parcMemory_Format("PARCRandomAccessFile[%s]@%p\n", instance->fname, instance); + return result; +} + +PARCRandomAccessFile * +parcRandomAccessFile_Open(PARCFile *file) +{ + PARCRandomAccessFile *handle = parcObject_CreateAndClearInstance(PARCRandomAccessFile); + if (handle != NULL) { + char *fname = parcFile_ToString(file); + handle->fhandle = fopen(fname, "r+"); + handle->fname = parcMemory_StringDuplicate(fname, strlen(fname)); + parcMemory_Deallocate(&fname); + } + return handle; +} + +bool +parcRandomAccessFile_Close(PARCRandomAccessFile *fileHandle) +{ + assertNotNull(fileHandle->fhandle, "Can't fclose a null pointer. How did they get one anyway?"); + bool result = fclose(fileHandle->fhandle) == 0; + fileHandle->fhandle = NULL; + parcMemory_Deallocate(&fileHandle->fname); + fileHandle->fname = NULL; + return result; +} + +// read (count * size) bytes into the provided buffer, and return the number of bytes actually read +size_t +parcRandomAccessFile_Read(PARCRandomAccessFile *fileHandle, PARCBuffer *buffer) +{ + size_t length = parcBuffer_Remaining(buffer); + size_t numBytes = fread(parcBuffer_Overlay(buffer, length), 1, length, fileHandle->fhandle); + return numBytes; +} + +// write (count * size) bytes from `buffer` to the file, and return the number of bytes actually written +size_t +parcRandomAccessFile_Write(PARCRandomAccessFile *fileHandle, PARCBuffer *buffer) +{ + size_t length = parcBuffer_Remaining(buffer); + size_t numBytes = fwrite(parcBuffer_Overlay(buffer, length), 1, length, fileHandle->fhandle); + return numBytes; +} + +size_t +parcRandomAccessFile_Seek(PARCRandomAccessFile *fileHandle, long offset, PARCRandomAccessFilePosition position) +{ + size_t result = 0; + switch (position) { + case PARCRandomAccessFilePosition_Start: + result = fseek(fileHandle->fhandle, offset, SEEK_SET); // beginning of the file + break; + case PARCRandomAccessFilePosition_Current: + result = fseek(fileHandle->fhandle, offset, SEEK_CUR); // current offset + break; + case PARCRandomAccessFilePosition_End: + result = fseek(fileHandle->fhandle, offset, SEEK_END); // end of the file + break; + default: + assertTrue(false, "Invalid position %d", position); + } + return result; +} |