fileObject.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "fileObject.h"
  23. IMPLEMENT_CONOBJECT(FileObject);
  24. bool FileObject::isEOF()
  25. {
  26. return mCurPos == mBufferSize;
  27. }
  28. FileObject::FileObject()
  29. {
  30. mFileBuffer = NULL;
  31. mBufferSize = 0;
  32. mCurPos = 0;
  33. }
  34. FileObject::~FileObject()
  35. {
  36. dFree(mFileBuffer);
  37. }
  38. void FileObject::close()
  39. {
  40. stream.close();
  41. dFree(mFileBuffer);
  42. mFileBuffer = NULL;
  43. mBufferSize = mCurPos = 0;
  44. }
  45. bool FileObject::openForWrite(const char *fileName, const bool append)
  46. {
  47. char buffer[1024];
  48. Con::expandPath(buffer, sizeof(buffer), fileName);
  49. close();
  50. if(buffer == NULL || *buffer == 0)
  51. return false;
  52. if ( !append )
  53. return( ResourceManager->openFileForWrite(stream, buffer) );
  54. // Use the WriteAppend flag so it doesn't clobber the existing file:
  55. if ( !ResourceManager->openFileForWrite(stream, buffer, File::WriteAppend) )
  56. return( false );
  57. stream.setPosition( stream.getStreamSize() );
  58. return( true );
  59. }
  60. bool FileObject::openForRead(const char* /*fileName*/)
  61. {
  62. AssertFatal(false, "Error, not yet implemented!");
  63. return false;
  64. }
  65. bool FileObject::readMemory(const char *fileName)
  66. {
  67. StringTableEntry fileToOpen = NULL;
  68. char buffer[1024];
  69. Con::expandPath( buffer, sizeof( buffer ), fileName );
  70. fileToOpen = StringTable->insert(buffer);
  71. close();
  72. Stream *s = ResourceManager->openStream(fileToOpen);
  73. if(!s)
  74. return false;
  75. mBufferSize = ResourceManager->getSize(fileToOpen);
  76. mFileBuffer = (U8 *) dMalloc(mBufferSize + 1);
  77. mFileBuffer[mBufferSize] = 0;
  78. s->read(mBufferSize, mFileBuffer);
  79. ResourceManager->closeStream(s);
  80. mCurPos = 0;
  81. return true;
  82. }
  83. const U8 *FileObject::readLine()
  84. {
  85. if(!mFileBuffer)
  86. return (U8 *) "";
  87. U32 tokPos = mCurPos;
  88. for(;;)
  89. {
  90. if(mCurPos == mBufferSize)
  91. break;
  92. if(mFileBuffer[mCurPos] == '\r')
  93. {
  94. mFileBuffer[mCurPos++] = 0;
  95. if(mFileBuffer[mCurPos] == '\n')
  96. mCurPos++;
  97. break;
  98. }
  99. if(mFileBuffer[mCurPos] == '\n')
  100. {
  101. mFileBuffer[mCurPos++] = 0;
  102. break;
  103. }
  104. mCurPos++;
  105. }
  106. return mFileBuffer + tokPos;
  107. }
  108. void FileObject::peekLine( U8* line, S32 length )
  109. {
  110. if(!mFileBuffer)
  111. {
  112. line[0] = '\0';
  113. return;
  114. }
  115. // Copy the line into the buffer. We can't do this like readLine because
  116. // we can't modify the file buffer.
  117. S32 i = 0;
  118. U32 tokPos = mCurPos;
  119. while( ( tokPos != mBufferSize ) && ( mFileBuffer[tokPos] != '\r' ) && ( mFileBuffer[tokPos] != '\n' ) && ( i < ( length - 1 ) ) )
  120. line[i++] = mFileBuffer[tokPos++];
  121. line[i++] = '\0';
  122. //if( i == length )
  123. //Con::warnf( "FileObject::peekLine - The line contents could not fit in the buffer (size %d). Truncating.", length );
  124. }
  125. void FileObject::writeLine(const U8 *line)
  126. {
  127. stream.write(dStrlen((const char *) line), line);
  128. stream.write(2, "\r\n");
  129. }
  130. void FileObject::writeObject( SimObject* object, const U8* objectPrepend )
  131. {
  132. if( objectPrepend == NULL )
  133. stream.write(2, "\r\n");
  134. else
  135. stream.write(dStrlen((const char *) objectPrepend), objectPrepend );
  136. object->write( stream, 0 );
  137. }
  138. ConsoleMethod( FileObject, openForRead, bool, 3, 3, "( filename ) Use the openForRead method to open a previously created file for reading.\n"
  139. "@param filename The path and filename of the file to open for reading.\n"
  140. "@return Returns true if the file was successfully opened for reading, false otherwise.\n"
  141. "@sa close, OpenForAppend, OpenForWrite")
  142. {
  143. return object->readMemory(argv[2]);
  144. }
  145. ConsoleMethod( FileObject, openForWrite, bool, 3, 3, "( filename ) Use the openForWrite method to previously created or a new file for writing. In either case, the file will be overwritten.\n"
  146. "@param filename The path and filename of the file to open for writing.\n"
  147. "@return Returns true if the file was successfully opened for writing, false otherwise.\n"
  148. "@sa close, OpenForAppend, openForRead")
  149. {
  150. return object->openForWrite(argv[2]);
  151. }
  152. ConsoleMethod( FileObject, openForAppend, bool, 3, 3, "( filename ) Use the openForAppend method to open a previously created file for appending. If the file specified by filename does not exist, the file is created first.\n"
  153. "@param filename The path and filename of the file to open for appending.\n"
  154. "@return Returns true if the file was successfully opened for appending, false otherwise.\n"
  155. "@sa close, openForRead, openForWrite")
  156. {
  157. return object->openForWrite(argv[2], true);
  158. }
  159. ConsoleMethod( FileObject, isEOF, bool, 2, 2, "() Use the isEOF method to check to see if the end of the current file (opened for read) has been reached.\n"
  160. "@return Returns true if the end of file has been reached, false otherwise.\n"
  161. "@sa openForRead")
  162. {
  163. return object->isEOF();
  164. }
  165. ConsoleMethod( FileObject, readLine, const char*, 2, 2, "() Use the readLine method to read a single line from a file previously opened for reading.\n"
  166. "Use isEOF to check for end of file while reading.\n"
  167. "@return Returns the next line in the file, or a NULL string if the end-of-file has been reached.\n"
  168. "@sa isEOF, openForRead")
  169. {
  170. return (const char *) object->readLine();
  171. }
  172. ConsoleMethod( FileObject, peekLine, const char*, 2, 2, "Read a line from the file without moving the stream position.")
  173. {
  174. char *line = Con::getReturnBuffer( 512 );
  175. object->peekLine( (U8*)line, 512 );
  176. return line;
  177. }
  178. ConsoleMethod( FileObject, writeLine, void, 3, 3, "( text ) Use the writeLine method to write a value ( text ) into a file that was previously opened for appending or over-writing.\n"
  179. "@param text The value to write to the file.\n"
  180. "@return No return value.\n"
  181. "@sa openForAppend, openForWrite")
  182. {
  183. object->writeLine((const U8 *) argv[2]);
  184. }
  185. ConsoleMethod( FileObject, close, void, 2, 2, "() Use the close method to close the current file handle. If the file was opened for writing, this flushes the contents of the last write to disk.\n"
  186. "@return No return value.\n"
  187. "@sa openForAppend, openForRead, openForWrite")
  188. {
  189. object->close();
  190. }
  191. ConsoleMethod( FileObject, writeObject, void, 3, 4, "FileObject.writeObject(SimObject, object prepend)" )
  192. {
  193. SimObject* obj = Sim::findObject( argv[2] );
  194. if( !obj )
  195. {
  196. Con::printf("FileObject::writeObject - Invalid Object!");
  197. return;
  198. }
  199. char *objName = NULL;
  200. if( argc == 4 )
  201. objName = (char*)argv[3];
  202. object->writeObject( obj, (const U8*)objName );
  203. }