Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "crazy_linker_line_reader.h" | |
| 6 | |
| 7 #include "crazy_linker_debug.h" | |
| 8 | |
| 9 // Set to 1 to enable debug logs here. | |
| 10 #define DEBUG_LINE_READER 0 | |
| 11 | |
| 12 #define LLOG(...) LOG_IF(DEBUG_LINE_READER, __VA_ARGS__) | |
| 13 | |
| 14 namespace crazy { | |
| 15 | |
| 16 LineReader::LineReader() : fd_(), buff_(buff0_) { | |
| 17 Reset(); | |
| 18 eof_ = true; | |
| 19 } | |
| 20 | |
| 21 LineReader::LineReader(const char* path) : fd_(), buff_(buff0_) { | |
| 22 Open(path); | |
| 23 } | |
| 24 | |
| 25 LineReader::~LineReader() { | |
| 26 Reset(); | |
| 27 } | |
| 28 | |
| 29 void LineReader::Open(const char* path) { | |
| 30 Reset(); | |
| 31 eof_ = !fd_.OpenReadOnly(path); | |
| 32 } | |
| 33 | |
| 34 void LineReader::Reset() { | |
| 35 if (buff_ != buff0_) | |
| 36 ::free(buff_); | |
| 37 | |
| 38 eof_ = false; | |
| 39 line_start_ = 0; | |
| 40 line_len_ = 0; | |
| 41 buff_size_ = 0; | |
| 42 buff_capacity_ = sizeof buff0_; | |
| 43 buff_ = buff0_; | |
| 44 } | |
| 45 | |
| 46 bool LineReader::GetNextLine() { | |
| 47 // Eat previous line. | |
| 48 line_start_ += line_len_; | |
| 49 line_len_ = 0; | |
| 50 | |
| 51 for (;;) { | |
| 52 LLOG("%s: LOOP line_start=%d buff_size=%d buff_capacity=%d\n", | |
| 53 __FUNCTION__, line_start_, buff_size_, buff_capacity_); | |
| 54 | |
| 55 // Find the end of the current line in the current buffer. | |
| 56 const char* line = buff_ + line_start_; | |
| 57 const char* line_end = reinterpret_cast<const char*>(::memchr(line, '\n', bu ff_size_ - line_start_)); | |
|
bulach
2013/09/09 16:14:15
nit: >80cols here and 62 below
digit1
2013/09/10 09:23:30
Done.
| |
| 58 if (line_end != NULL) { | |
| 59 // Found one, return it directly. | |
| 60 line_len_ = static_cast<size_t>(line_end + 1 - line); | |
| 61 LLOG("%s: LINE line_start=%d line_len=%d '%.*s'\n", | |
| 62 __FUNCTION__, line_start_, line_len_, line_len_, buff_ + line_start_) ; | |
| 63 return true; | |
| 64 } | |
| 65 | |
| 66 // Eat the start of the buffer | |
| 67 if (line_start_ > 0) { | |
| 68 ::memmove(buff_, buff_ + line_start_, buff_size_ - line_start_); | |
| 69 buff_size_ -= line_start_; | |
| 70 line_start_ = 0; | |
| 71 LLOG("%s: MOVE buff_size=%d\n", __FUNCTION__, buff_size_); | |
| 72 } | |
| 73 | |
| 74 // Handle end of input now. | |
| 75 if (eof_) { | |
| 76 // If there is a last line that isn't terminated by a newline, and | |
| 77 // there is room for it in the buffer. Manually add a \n and return | |
| 78 // the line. | |
| 79 if (buff_size_ > 0 && buff_size_ < buff_capacity_) { | |
| 80 buff_[buff_size_++] = '\n'; | |
| 81 line_len_ = buff_size_; | |
| 82 LLOG("%s: EOF_LINE buff_size=%d '%.*s'\n", | |
| 83 __FUNCTION__, buff_size_, buff_size_, buff_); | |
| 84 return true; | |
| 85 } | |
| 86 // Otherwise, ignore the last line. | |
| 87 LLOG("%s: EOF\n", __FUNCTION__); | |
| 88 return false; | |
| 89 } | |
| 90 | |
| 91 // Before reading more data, grow the buffer if needed. | |
| 92 if (buff_size_ == buff_capacity_) { | |
| 93 size_t new_capacity = buff_capacity_ * 2; | |
| 94 void* old_buff = (buff_ == buff0_) ? NULL : buff_; | |
| 95 buff_ = static_cast<char*>(::realloc(old_buff, new_capacity)); | |
| 96 if (old_buff != buff_) | |
| 97 ::memcpy(buff_, buff0_, buff_capacity_); | |
| 98 | |
| 99 buff_capacity_ = new_capacity; | |
| 100 LLOG("%s: GROW buff_size=%d buff_capacity=%d '%.*s'\n", | |
| 101 __FUNCTION__, buff_size_, buff_capacity_, buff_size_, buff_); | |
| 102 } | |
| 103 | |
| 104 // Try to fill the rest of buffer after current content. | |
| 105 size_t avail = buff_capacity_ - buff_size_; | |
| 106 int ret = fd_.Read(buff_ + buff_size_, avail); | |
| 107 LLOG("%s: READ buff_size=%d buff_capacity=%d avail=%d ret=%d\n", | |
| 108 __FUNCTION__, buff_size_, buff_capacity_, avail, ret); | |
| 109 if (ret <= 0) { | |
| 110 eof_ = true; | |
| 111 ret = 0; | |
| 112 } | |
| 113 buff_size_ += static_cast<size_t>(ret); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 const char* LineReader::line() const { | |
| 118 return buff_ + line_start_; | |
| 119 } | |
| 120 | |
| 121 size_t LineReader::length() const { | |
| 122 return line_len_; | |
| 123 } | |
| 124 | |
| 125 } // namespace crazy | |
| OLD | NEW |