U_CAPI UBool U_EXPORT2 ucbuf_autodetect_fs(FileStream* in, const char** cp, UConverter** conv, int32_t* signatureLength, UErrorCode* error){ char start[8]; int32_t numRead; UChar target[1]={ 0 }; UChar* pTarget; const char* pStart; /* read a few bytes */ numRead=T_FileStream_read(in, start, sizeof(start)); *cp = ucnv_detectUnicodeSignature(start, numRead, signatureLength, error); /* unread the bytes beyond what was consumed for U+FEFF */ T_FileStream_rewind(in); if (*signatureLength > 0) { numRead = T_FileStream_read(in, start, *signatureLength); } if(*cp==NULL){ *conv =NULL; return FALSE; } /* open the converter for the detected Unicode charset */ *conv = ucnv_open(*cp,error); /* convert and ignore initial U+FEFF, and the buffer overflow */ pTarget = target; pStart = start; ucnv_toUnicode(*conv, &pTarget, target+1, &pStart, start+*signatureLength, NULL, FALSE, error); *signatureLength = (int32_t)(pStart - start); if(*error==U_BUFFER_OVERFLOW_ERROR) { *error=U_ZERO_ERROR; } /* verify that we successfully read exactly U+FEFF */ if(U_SUCCESS(*error) && (pTarget!=(target+1) || target[0]!=0xfeff)) { *error=U_INTERNAL_PROGRAM_ERROR; } return TRUE; }
/* rewind the buf and file stream */ U_CAPI void U_EXPORT2 ucbuf_rewind(UCHARBUF* buf,UErrorCode* error){ if(error==NULL || U_FAILURE(*error)){ return; } if(buf){ buf->currentPos=buf->buffer; buf->bufLimit=buf->buffer; T_FileStream_rewind(buf->in); buf->remaining=T_FileStream_size(buf->in)-buf->signatureLength; ucnv_resetToUnicode(buf->conv); if(buf->signatureLength>0) { UChar target[1]={ 0 }; UChar* pTarget; char start[8]; const char* pStart; int32_t numRead; /* read the signature bytes */ numRead=T_FileStream_read(buf->in, start, buf->signatureLength); /* convert and ignore initial U+FEFF, and the buffer overflow */ pTarget = target; pStart = start; ucnv_toUnicode(buf->conv, &pTarget, target+1, &pStart, start+numRead, NULL, FALSE, error); if(*error==U_BUFFER_OVERFLOW_ERROR) { *error=U_ZERO_ERROR; } /* verify that we successfully read exactly U+FEFF */ if(U_SUCCESS(*error) && (numRead!=buf->signatureLength || pTarget!=(target+1) || target[0]!=0xfeff)) { *error=U_INTERNAL_PROGRAM_ERROR; } } } }
/* * Opens the given fileName and reads in the information storing the data in flagBuffer. */ U_CAPI int32_t U_EXPORT2 parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, const char ** flagNames, int32_t numOfFlags, UErrorCode *status) { char* buffer = NULL; char* tmpFlagBuffer = NULL; UBool allocateMoreSpace = FALSE; int32_t idx, i; int32_t result = 0; FileStream *f = T_FileStream_open(fileName, "r"); if (f == NULL) { *status = U_FILE_ACCESS_ERROR; goto parseFlagsFile_cleanup; } buffer = uprv_malloc(sizeof(char) * currentBufferSize); tmpFlagBuffer = uprv_malloc(sizeof(char) * flagBufferSize); if (buffer == NULL || tmpFlagBuffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto parseFlagsFile_cleanup; } do { if (allocateMoreSpace) { allocateMoreSpace = FALSE; currentBufferSize *= 2; uprv_free(buffer); buffer = uprv_malloc(sizeof(char) * currentBufferSize); if (buffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto parseFlagsFile_cleanup; } } for (i = 0; i < numOfFlags;) { if (T_FileStream_readLine(f, buffer, currentBufferSize) == NULL) { /* End of file reached. */ break; } if (buffer[0] == '#') { continue; } if (uprv_strlen(buffer) == (currentBufferSize - 1) && buffer[currentBufferSize-2] != '\n') { /* Allocate more space for buffer if it didnot read the entrire line */ allocateMoreSpace = TRUE; T_FileStream_rewind(f); break; } else { idx = extractFlag(buffer, currentBufferSize, tmpFlagBuffer, flagBufferSize, flagNames, numOfFlags, status); if (U_FAILURE(*status)) { if (*status == U_BUFFER_OVERFLOW_ERROR) { result = currentBufferSize; } else { result = -1; } break; } else { if (flagNames != NULL) { if (idx >= 0) { uprv_strcpy(flagBuffer[idx], tmpFlagBuffer); } else { /* No match found. Skip it. */ continue; } } else { uprv_strcpy(flagBuffer[i++], tmpFlagBuffer); } } } } } while (allocateMoreSpace && U_SUCCESS(*status)); parseFlagsFile_cleanup: uprv_free(tmpFlagBuffer); uprv_free(buffer); T_FileStream_close(f); if (U_FAILURE(*status)) { return -1; } if (U_SUCCESS(*status) && result == 0) { currentBufferSize = DEFAULT_BUFFER_SIZE; } return result; }
static void TestFileStream(void){ int32_t c = 0; int32_t c1=0; UErrorCode status = U_ZERO_ERROR; const char* testdatapath = loadTestData(&status); char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10); FileStream* stream = NULL; /* these should not be closed */ FileStream* pStdin = T_FileStream_stdin(); FileStream* pStdout = T_FileStream_stdout(); FileStream* pStderr = T_FileStream_stderr(); const char* testline = "This is a test line"; int32_t bufLen = (int32_t)strlen(testline)+10; char* buf = (char*) malloc(bufLen); int32_t retLen = 0; if(pStdin==NULL){ log_err("failed to get T_FileStream_stdin()"); } if(pStdout==NULL){ log_err("failed to get T_FileStream_stdout()"); } if(pStderr==NULL){ log_err("failed to get T_FileStream_stderr()"); } uprv_strcpy(fileName,testdatapath); uprv_strcat(fileName,".dat"); stream = T_FileStream_open(fileName, "r"); if(stream==NULL){ log_data_err("T_FileStream_open failed to open %s\n",fileName); } else { if(!T_FileStream_file_exists(fileName)){ log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName); } retLen=T_FileStream_read(stream,&c,1); if(retLen==0){ log_data_err("T_FileStream_read failed to read from %s \n",fileName); } retLen=0; T_FileStream_rewind(stream); T_FileStream_read(stream,&c1,1); if(c!=c1){ log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName); } T_FileStream_rewind(stream); c1 = T_FileStream_peek(stream); if(c!=c1){ log_data_err("T_FileStream_peek failed to peekd %s \n",fileName); } c = T_FileStream_getc(stream); T_FileStream_ungetc(c,stream); if(c!= T_FileStream_getc(stream)){ log_data_err("T_FileStream_ungetc failed to d %s \n",fileName); } if(T_FileStream_size(stream)<=0){ log_data_err("T_FileStream_size failed to d %s \n",fileName); } if(T_FileStream_error(stream)){ log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName); } if(!T_FileStream_error(NULL)){ log_err("T_FileStream_error didn't get an error %s\n",fileName); } T_FileStream_putc(stream, 0x20); if(!T_FileStream_error(stream)){ /* Warning writing to a read-only file may not consistently fail on all platforms (e.g. HP-UX, FreeBSD, MacOSX) */ log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName); } T_FileStream_close(stream); } /* test writing function */ stream=NULL; uprv_strcpy(fileName,testdatapath); uprv_strcat(fileName,".tmp"); stream = T_FileStream_open(fileName,"w+"); if(stream == NULL){ log_data_err("Could not open %s for writing\n",fileName); } else { c= '$'; T_FileStream_putc(stream,c); T_FileStream_rewind(stream); if(c != T_FileStream_getc(stream)){ log_data_err("T_FileStream_putc failed %s\n",fileName); } T_FileStream_rewind(stream); T_FileStream_writeLine(stream,testline); T_FileStream_rewind(stream); T_FileStream_readLine(stream,buf,bufLen); if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){ log_data_err("T_FileStream_writeLine failed %s\n",fileName); } T_FileStream_rewind(stream); T_FileStream_write(stream,testline,(int32_t)strlen(testline)); T_FileStream_rewind(stream); retLen = T_FileStream_read(stream, buf, bufLen); if(uprv_strncmp(testline, buf,retLen)!=0){ log_data_err("T_FileStream_write failed %s\n",fileName); } T_FileStream_close(stream); } if(!T_FileStream_remove(fileName)){ log_data_err("T_FileStream_remove failed to delete %s\n",fileName); } free(fileName); free(buf); }
/* * Opens the given fileName and reads in the information storing the data in flagBuffer. */ U_CAPI int32_t U_EXPORT2 parseFlagsFile(const char *fileName, char **flagBuffer, int32_t flagBufferSize, int32_t numOfFlags, UErrorCode *status) { char* buffer = uprv_malloc(sizeof(char) * currentBufferSize); UBool allocateMoreSpace = FALSE; int32_t i; int32_t result = 0; FileStream *f = T_FileStream_open(fileName, "r"); if (f == NULL) { *status = U_FILE_ACCESS_ERROR; return -1; } if (buffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return -1; } do { if (allocateMoreSpace) { allocateMoreSpace = FALSE; currentBufferSize *= 2; uprv_free(buffer); buffer = uprv_malloc(sizeof(char) * currentBufferSize); if (buffer == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return -1; } } for (i = 0; i < numOfFlags; i++) { if (T_FileStream_readLine(f, buffer, currentBufferSize) == NULL) { *status = U_FILE_ACCESS_ERROR; break; } if (uprv_strlen(buffer) == (currentBufferSize - 1) && buffer[currentBufferSize-2] != '\n') { /* Allocate more space for buffer if it didnot read the entrire line */ allocateMoreSpace = TRUE; T_FileStream_rewind(f); break; } else { extractFlag(buffer, currentBufferSize, flagBuffer[i], flagBufferSize, status); if (U_FAILURE(*status)) { if (*status == U_BUFFER_OVERFLOW_ERROR) { result = currentBufferSize; } else { result = -1; } break; } } } } while (allocateMoreSpace && U_SUCCESS(*status)); uprv_free(buffer); T_FileStream_close(f); if (U_SUCCESS(*status) && result == 0) { currentBufferSize = DEFAULT_BUFFER_SIZE; } return result; }