handle last line without line break better
[ecparse.git] / CollectionReader.cpp
1 /**
2  * © 2008 by David Roden <droden@gmail.com>
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include "CollectionReader.h"
8 #include "GlobalSettings.h"
9
10 CollectionReader::CollectionReader(ReaderInput* readerInput) {
11         this->readerInput = readerInput;
12         firstLink = true;
13 }
14
15 CollectionReader::~CollectionReader() {
16 }
17
18 bool CollectionReader::isLineBreakPresent() {
19         size_t indexOfLineBreak = growingBuffer.indexOf('\n');
20         GlobalSettings::isVerbose() && (indexOfLineBreak != (size_t) -1) && fprintf(stderr, "[%s:%d] found line break at %d.\n", __FILE__, __LINE__, indexOfLineBreak);
21         GlobalSettings::isVerbose() && (indexOfLineBreak == (size_t) -1) && fprintf(stderr, "[%s:%d] could not find line break.\n", __FILE__, __LINE__);
22         return indexOfLineBreak != (size_t) -1;
23 }
24
25 ED2KLink* CollectionReader::getNextLink() {
26         if (readerInput->isEOF() && !growingBuffer.getRemaining()) {
27                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] readInput EOF reached.\n", __FILE__, __LINE__);
28                 return NULL;
29         }
30         if (firstLink) {
31                 identifyCollectionType();
32                 if (readerInput->isEOF() && !growingBuffer.getRemaining()) {
33                         GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] readInput EOF reached.\n", __FILE__, __LINE__);
34                         return NULL;
35                 }
36                 firstLink = false;
37         }
38         if (isTextCollection) {
39                 while (!readerInput->isEOF() && !isLineBreakPresent()) {
40                         readMoreBytes();
41                 }
42                 if (readerInput->isEOF() && !growingBuffer.getRemaining()) {
43                         GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] readInput EOF reached.\n", __FILE__, __LINE__);
44                         return NULL;
45                 }
46                 size_t indexOfLineBreak = growingBuffer.indexOf('\n');
47                 char* line;
48                 if (indexOfLineBreak == (size_t) -1) {
49                         GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] could not find line break, using remainder of file.\n", __FILE__, __LINE__);
50                         indexOfLineBreak = growingBuffer.getRemaining();
51                         line = (char*) malloc(indexOfLineBreak + 1);
52                         growingBuffer.read(line, indexOfLineBreak);
53                         line[indexOfLineBreak] = '\0';
54                 } else {
55                         line = (char*) malloc(indexOfLineBreak + 1);
56                         growingBuffer.read(line, indexOfLineBreak + 1);
57                         if (line[indexOfLineBreak] == '\n') {
58                                 line[indexOfLineBreak] = '\0';
59                         }
60                         if (line[indexOfLineBreak - 1] == '\r') {
61                                 line[indexOfLineBreak - 1] = '\0';
62                         }
63                 }
64                 growingBuffer.cut();
65                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] got line: %s\n", __FILE__, __LINE__, line);
66                 ED2KLink* ed2kLink = ED2KLink::parseED2KLink(line);
67                 free(line);
68                 return ed2kLink;
69         } else {
70         }
71         return NULL;
72 }
73
74 void CollectionReader::readMoreBytes() {
75         char buffer[1024];
76         size_t readBytes;
77
78         readBytes = readerInput->read(buffer, 1024);
79         growingBuffer.write(buffer, readBytes);
80 }
81
82 void CollectionReader::identifyCollectionType() {
83         int version;
84         size_t readBytes;
85
86         readBytes = readerInput->read(&version, 4);
87         if ((readBytes < 4) || readerInput->isEOF()) {
88                 return;
89         }
90         if (version == 0x01) {
91                 isTextCollection = false;
92                 this->version = 1;
93                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] identified binary collection, version 1\n", __FILE__, __LINE__);
94         } else if (version == 0x02) {
95                 isTextCollection = false;
96                 this->version = 2;
97                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] identified binary collection, version 2\n", __FILE__, __LINE__);
98         } else if (!strncmp("ed2k", (char*) &version, 4)) {
99                 isTextCollection = true;
100                 growingBuffer.write(&version, 4);
101                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] identified text collection\n", __FILE__, __LINE__);
102         } else  {
103                 GlobalSettings::isVerbose() && fprintf(stderr, "[%s:%d] could not identify collection!\n", __FILE__, __LINE__);
104         }
105 }
106