int newline(int sect, char *line) /* **-------------------------------------------------------------- ** Input: sect = current section of input file ** *line = line read from input file ** Output: returns error code or 0 if no error found ** Purpose: processes a new line of data from input file **-------------------------------------------------------------- */ { int n; switch (sect) { case _TITLE: if (Ntitle < 3) { n = strlen(line); if (line[n-1] == 10) line[n-1] = ' '; strncpy(Title[Ntitle],line,MAXMSG); Ntitle++; } return(0); case _JUNCTIONS: return(juncdata()); case _RESERVOIRS: case _TANKS: return(tankdata()); case _PIPES: return(pipedata()); case _PUMPS: return(pumpdata()); case _VALVES: return(valvedata()); case _PATTERNS: return(patterndata()); case _CURVES: return(curvedata()); case _DEMANDS: return(demanddata()); case _CONTROLS: return(controldata()); case _RULES: return(ruledata()); /* See RULES.C */ case _SOURCES: return(sourcedata()); case _EMITTERS: return(emitterdata()); case _QUALITY: return(qualdata()); case _STATUS: return(statusdata()); case _ROUGHNESS: return(0); case _ENERGY: return(energydata()); case _REACTIONS: return(reactdata()); case _MIXING: return(mixingdata()); case _REPORT: return(reportdata()); case _TIMES: return(timedata()); case _OPTIONS: return(optiondata()); /* Data in these sections are not used for any computations */ case _COORDS: return(0); case _LABELS: return(0); case _TAGS: return(0); case _VERTICES: return(0); case _BACKDROP: return(0); } return(201); } /* end of newline */
int inbuffer::providedata(unsigned int amount, long long position) { if (position < 0 || position >= filesize) return 0; if (position + amount > filesize) amount = filesize - position; if (position >= pos && position + amount <= pos + writepos) { readpos = position - pos; return inbytes(); } if (pipe_mode) { if (position < pos) return -1; // can't go backwards! return pipedata(amount, position); } std::vector<infile>::const_iterator i = files.begin(); assert(i != files.end()); // otherwise we would have returned already while (position >= i->end) { #ifdef POSIX_FADV_DONTNEED if (sequential) { off_t len = i->end - i->off; posix_fadvise(i->fd, 0, len, POSIX_FADV_DONTNEED); } #endif ++i; assert(i != files.end()); } assert(position >= i->off); #ifndef __WIN32_ // remove old mapping, if any if (mmapped) { ::munmap(d, writepos); mmapped = false; d = 0; } if (mmapsize > 0 && position + amount <= i->end) { // calculate mmap window tvclipper_off_t newpos = position + amount - mmapsize / 2; if (newpos > position) newpos = position; else if (newpos < i->off) newpos = i->off; // align to pagesize // note: relpos must be aligned, NOT newpos! off_t relpos = newpos - i->off; size_t modulus = relpos % pagesize; relpos -= modulus; newpos -= modulus; #ifdef POSIX_FADV_DONTNEED if (sequential) { // we're done with earlier parts if (relpos) posix_fadvise(i->fd, 0, relpos, POSIX_FADV_DONTNEED); } #endif size_t len = mmapsize; if (newpos + len > static_cast<size_t>(i->end)) len = i->end - newpos; void *ptr = ::mmap(0, len, PROT_READ, MAP_SHARED, i->fd, relpos); if (ptr != MAP_FAILED) { // mmap succeeded if (d) free(d); d = ptr; readpos = position - newpos; writepos = len; pos = newpos; mmapped = true; return inbytes(); } } #endif // allocate read buffer if (!d) { d = (void*) calloc(1, size); if (!d) { fprintf(stderr, "inbuffer::providedata: can't allocate %ld bytes: %s\n", (long)size, strerror(errno)); abort(); } readpos = 0; writepos = 0; pos = 0; } if (amount > size) amount = size; // reuse existing data if possible if (position >= pos && position < pos + writepos) { unsigned int pp = position - pos; if (pp > 0) { writepos -= pp; memmove(d, (char*)d + pp, writepos); } } else { writepos = 0; } readpos = 0; pos = position; bool needseek = true; while (writepos < amount) { tvclipper_off_t seekpos = pos + writepos; while (seekpos >= i->end) { ++i; assert(i != files.end()); needseek = true; } assert(seekpos >= i->off); if (needseek) { #ifdef __WIN32_ __int64 relpos = seekpos - i->off; if (::_lseeki64(i->fd, relpos, SEEK_SET) == -1) #else /* __WIN32__ */ off_t relpos = seekpos - i->off; if (::lseek(i->fd, relpos, SEEK_SET) == -1) #endif /* __WIN32__ */ return -1; needseek = false; } size_t len = size - writepos; if (len > static_cast<size_t>(i->end - seekpos)) len = i->end - seekpos; assert(len > 0); ssize_t n = ::read(i->fd, (char*)d + writepos, len); if (n == -1) return -1; if (n == 0) { // this should NOT happen! eof = true; break; } writepos += n; } return inbytes(); }