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 |