1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0030830: Point Cloud Rendering - use temporary buffer to read lines from .pts and .ptx files

Add Standard_ReadLineBuffer - auxiliary tool for buffered reading of lines from input stream.
This commit is contained in:
osa 2019-07-24 14:30:53 +03:00 committed by bugmaster
parent 9460f8c0b9
commit fa1710b567
2 changed files with 199 additions and 0 deletions

View File

@ -77,6 +77,7 @@ Standard_PrimitiveTypes.hxx
Standard_ProgramError.hxx
Standard_RangeError.hxx
Standard_ReadBuffer.hxx
Standard_ReadLineBuffer.hxx
Standard_Real.cxx
Standard_Real.hxx
Standard_ShortReal.cxx

View File

@ -0,0 +1,198 @@
// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _Standard_ReadLineBuffer_HeaderFile
#define _Standard_ReadLineBuffer_HeaderFile
#include <iostream>
#include <vector>
//! Auxiliary tool for buffered reading of lines from input stream.
class Standard_ReadLineBuffer
{
public:
//! Constructor with initialization.
//! @param theMaxBufferSizeBytes the length of buffer to read (in bytes)
Standard_ReadLineBuffer (size_t theMaxBufferSizeBytes)
: myUseReadBufferLastStr(false),
myBufferPos (0),
myBytesLastRead (0)
{
// allocate read buffer
myReadBuffer.resize (theMaxBufferSizeBytes);
}
//! Destructor.
virtual ~Standard_ReadLineBuffer() {}
//! Clear buffer and cached values.
void Clear()
{
myReadBufferLastStr.clear();
myUseReadBufferLastStr = false;
myBufferPos = 0;
myBytesLastRead = 0;
}
//! Read next line from the stream.
//! @return pointer to the line or NULL on error / end of reading buffer
//! (in case of NULL result theStream should be checked externally to identify the presence of errors).
//! Empty lines will be returned also with zero length.
//! @param theLineLength [out] - output parameter defined length of returned line.
template<typename Stream_T>
const char* ReadLine (Stream_T& theStream,
size_t& theLineLength)
{
int64_t aReadData = 0;
return ReadLine (theStream, theLineLength, aReadData);
}
//! Read next line from the stream.
//! @return pointer to the line or NULL on error / end of reading buffer
//! (in case of NULL result theStream should be checked externally to identify the presence of errors).
//! Empty lines will be returned also with zero length.
//! @param theLineLength [out] - output parameter defined length of returned line.
//! @param theReadData [out] - output parameter defined the number of elements successfully read from the stream during this call,
//! it can be zero if no data was read and the line is taken from the buffer.
template<typename Stream_T>
const char* ReadLine (Stream_T& theStream,
size_t& theLineLength,
int64_t& theReadData)
{
char* aResultLine = NULL;
theLineLength = 0;
theReadData = 0;
while (aResultLine == NULL)
{
if (myBufferPos == 0 || myBufferPos >= (myBytesLastRead))
{
// read new chunk from the stream
if (!readStream (theStream, myReadBuffer.size(), myBytesLastRead))
{
// error during file reading
break;
}
theReadData = myBytesLastRead;
if (myBytesLastRead > 0)
{
myBufferPos = 0;
}
else
{
// end of the stream
if (myUseReadBufferLastStr)
{
theLineLength = myReadBufferLastStr.size();
aResultLine = myReadBufferLastStr.data();
myUseReadBufferLastStr = false;
}
break;
}
}
size_t aStartLinePos = myBufferPos;
bool isEndLineFound = false;
// read next line from myReadBuffer
while (myBufferPos < myBytesLastRead)
{
if (myReadBuffer[myBufferPos] == '\n')
{
isEndLineFound = true;
}
++myBufferPos;
if (isEndLineFound) break;
}
if (isEndLineFound)
{
if (myUseReadBufferLastStr)
{
// append current string to the last "unfinished" string of the previous chunk
myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = false;
theLineLength = myReadBufferLastStr.size();
aResultLine = myReadBufferLastStr.data();
}
else
{
if (myReadBufferLastStr.size() > 0)
{
myReadBufferLastStr.clear();
}
theLineLength = myBufferPos - aStartLinePos;
aResultLine = myReadBuffer.data() + aStartLinePos;
}
// make string null terminated by replacing '\n' or '\r' (before '\n') symbol to null character.
if (theLineLength > 1 && aResultLine[theLineLength - 2] == '\r')
{
aResultLine[theLineLength - 2] = '\0';
theLineLength -= 2;
}
else
{
aResultLine[theLineLength - 1] = '\0';
theLineLength -= 1;
}
}
else
{
// save "unfinished" part of string to additional buffer
if (aStartLinePos != myBufferPos)
{
myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
myUseReadBufferLastStr = true;
}
}
}
return aResultLine;
}
protected:
//! Read from stl stream.
//! @return true if reading was finished without errors.
bool readStream (std::istream& theStream,
size_t theLen,
size_t& theReadLen)
{
theReadLen = theStream.read (myReadBuffer.data(), theLen).gcount();
return !theStream.bad();
}
//! Read from FILE stream.
//! @return true if reading was finished without errors.
bool readStream (FILE* theStream,
size_t theLen,
size_t& theReadLen)
{
theReadLen = ::fread (myReadBuffer.data(), 1, theLen, theStream);
return ::ferror (theStream) == 0;
}
protected:
std::vector<char> myReadBuffer; //!< Temp read buffer
std::vector<char> myReadBufferLastStr; //!< Part of last string of myReadBuffer
bool myUseReadBufferLastStr; //!< Flag to use myReadBufferLastStr during next line reading
size_t myBufferPos; //!< Current position in myReadBuffer
size_t myBytesLastRead; //!< The number of characters that were read last time from myReadBuffer.
};
#endif // _Standard_ReadLineBuffer_HeaderFile