diff options
-rw-r--r-- | include/utils/String8.h | 11 | ||||
-rw-r--r-- | include/utils/Tokenizer.h | 4 | ||||
-rw-r--r-- | libs/utils/FileMap.cpp | 8 | ||||
-rw-r--r-- | libs/utils/String8.cpp | 18 | ||||
-rw-r--r-- | libs/utils/Tokenizer.cpp | 45 |
5 files changed, 63 insertions, 23 deletions
diff --git a/include/utils/String8.h b/include/utils/String8.h index 6abfb06..6b49ff5 100644 --- a/include/utils/String8.h +++ b/include/utils/String8.h @@ -47,7 +47,12 @@ public: explicit String8(const char32_t* o); explicit String8(const char32_t* o, size_t numChars); ~String8(); - + + static inline const String8 empty(); + + static String8 format(const char* fmt, ...) __attribute__((format (printf, 1, 2))); + static String8 formatV(const char* fmt, va_list args); + inline const char* string() const; inline size_t size() const; inline size_t length() const; @@ -229,6 +234,10 @@ inline int strictly_order_type(const String8& lhs, const String8& rhs) return compare_type(lhs, rhs) < 0; } +inline const String8 String8::empty() { + return String8(); +} + inline const char* String8::string() const { return mString; diff --git a/include/utils/Tokenizer.h b/include/utils/Tokenizer.h index 21e58e6..c7db5fb 100644 --- a/include/utils/Tokenizer.h +++ b/include/utils/Tokenizer.h @@ -28,7 +28,7 @@ namespace android { * A simple tokenizer for loading and parsing ASCII text files line by line. */ class Tokenizer { - Tokenizer(const String8& filename, FileMap* fileMap, const char* buffer, size_t length); + Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length); public: ~Tokenizer(); @@ -110,7 +110,7 @@ private: String8 mFilename; FileMap* mFileMap; - const char* mBuffer; + char* mBuffer; size_t mLength; const char* mCurrent; diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp index e1ba9b2..f1f8bda 100644 --- a/libs/utils/FileMap.cpp +++ b/libs/utils/FileMap.cpp @@ -63,16 +63,18 @@ FileMap::~FileMap(void) free(mFileName); } #ifdef HAVE_POSIX_FILEMAP - if (munmap(mBasePtr, mBaseLength) != 0) { + if (mBasePtr && munmap(mBasePtr, mBaseLength) != 0) { LOGD("munmap(%p, %d) failed\n", mBasePtr, (int) mBaseLength); } #endif #ifdef HAVE_WIN32_FILEMAP - if ( UnmapViewOfFile(mBasePtr) == 0) { + if (mBasePtr && UnmapViewOfFile(mBasePtr) == 0) { LOGD("UnmapViewOfFile(%p) failed, error = %ld\n", mBasePtr, GetLastError() ); } - CloseHandle(mFileMapping); + if (mFileMapping != INVALID_HANDLE_VALUE) { + CloseHandle(mFileMapping); + } CloseHandle(mFileHandle); #endif } diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp index e531a2a..0bc5aff 100644 --- a/libs/utils/String8.cpp +++ b/libs/utils/String8.cpp @@ -195,6 +195,24 @@ String8::~String8() SharedBuffer::bufferFromData(mString)->release(); } +String8 String8::format(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + + String8 result(formatV(fmt, args)); + + va_end(args); + return result; +} + +String8 String8::formatV(const char* fmt, va_list args) +{ + String8 result; + result.appendFormatV(fmt, args); + return result; +} + void String8::clear() { SharedBuffer::bufferFromData(mString)->release(); mString = getEmptyString(); diff --git a/libs/utils/Tokenizer.cpp b/libs/utils/Tokenizer.cpp index 9251973..b3445b7 100644 --- a/libs/utils/Tokenizer.cpp +++ b/libs/utils/Tokenizer.cpp @@ -35,16 +35,16 @@ static inline bool isDelimiter(char ch, const char* delimiters) { return strchr(delimiters, ch) != NULL; } - -Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, - const char* buffer, size_t length) : - mFilename(filename), mFileMap(fileMap), mBuffer(buffer), mLength(length), - mCurrent(buffer), mLineNumber(1) { +Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer, size_t length) : + mFilename(filename), mFileMap(fileMap), + mBuffer(buffer), mLength(length), mCurrent(buffer), mLineNumber(1) { } Tokenizer::~Tokenizer() { if (mFileMap) { mFileMap->release(); + } else { + delete[] mBuffer; } } @@ -63,22 +63,33 @@ status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) { LOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno)); } else { size_t length = size_t(stat.st_size); + FileMap* fileMap = new FileMap(); - if (!fileMap->create(NULL, fd, 0, length, true)) { - result = NO_MEMORY; - LOGE("Error mapping file '%s', %s.", filename.string(), strerror(errno)); - } else { + char* buffer; + if (fileMap->create(NULL, fd, 0, length, true)) { fileMap->advise(FileMap::SEQUENTIAL); - - *outTokenizer = new Tokenizer(filename, fileMap, - static_cast<const char*>(fileMap->getDataPtr()), length); - if (!*outTokenizer) { - result = NO_MEMORY; - LOGE("Error allocating tokenizer for file=%s.", filename.string()); + buffer = static_cast<char*>(fileMap->getDataPtr()); + } else { + fileMap->release(); + fileMap = NULL; + + // Fall back to reading into a buffer since we can't mmap files in sysfs. + // The length we obtained from stat is wrong too (it will always be 4096) + // so we must trust that read will read the entire file. + buffer = new char[length]; + ssize_t nrd = read(fd, buffer, length); + if (nrd < 0) { + result = -errno; + LOGE("Error reading file '%s', %s.", filename.string(), strerror(errno)); + delete[] buffer; + buffer = NULL; + } else { + length = size_t(nrd); } } - if (result) { - fileMap->release(); + + if (!result) { + *outTokenizer = new Tokenizer(filename, fileMap, buffer, length); } } close(fd); |