File indexing completed on 2025-01-18 10:04:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _Standard_ReadLineBuffer_HeaderFile
0015 #define _Standard_ReadLineBuffer_HeaderFile
0016
0017 #include <iostream>
0018 #include <vector>
0019
0020
0021 class Standard_ReadLineBuffer
0022 {
0023 public:
0024
0025
0026
0027 Standard_ReadLineBuffer (size_t theMaxBufferSizeBytes)
0028 : myUseReadBufferLastStr(false),
0029 myIsMultilineMode (false),
0030 myToPutGapInMultiline (true),
0031 myBufferPos (0),
0032 myBytesLastRead (0)
0033 {
0034
0035 myReadBuffer.resize (theMaxBufferSizeBytes);
0036 }
0037
0038
0039 virtual ~Standard_ReadLineBuffer() {}
0040
0041
0042 void Clear()
0043 {
0044 myReadBufferLastStr.clear();
0045 myUseReadBufferLastStr = false;
0046 myIsMultilineMode = false;
0047 myToPutGapInMultiline = true;
0048 myBufferPos = 0;
0049 myBytesLastRead = 0;
0050 }
0051
0052
0053
0054
0055
0056
0057
0058 template<typename Stream_T>
0059 const char* ReadLine (Stream_T& theStream,
0060 size_t& theLineLength)
0061 {
0062 int64_t aReadData = 0;
0063 return ReadLine (theStream, theLineLength, aReadData);
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template<typename Stream_T>
0075 const char* ReadLine (Stream_T& theStream,
0076 size_t& theLineLength,
0077 int64_t& theReadData)
0078 {
0079 char* aResultLine = NULL;
0080 bool isMultiline = false;
0081 theLineLength = 0;
0082 theReadData = 0;
0083
0084 while (aResultLine == NULL)
0085 {
0086 if (myBufferPos == 0 || myBufferPos >= (myBytesLastRead))
0087 {
0088
0089 if (!readStream (theStream, myReadBuffer.size(), myBytesLastRead))
0090 {
0091
0092 break;
0093 }
0094
0095 theReadData = myBytesLastRead;
0096
0097 if (myBytesLastRead > 0)
0098 {
0099 myBufferPos = 0;
0100 }
0101 else
0102 {
0103
0104 if (myUseReadBufferLastStr)
0105 {
0106 theLineLength = myReadBufferLastStr.size();
0107 aResultLine = &myReadBufferLastStr.front();
0108 myUseReadBufferLastStr = false;
0109 }
0110 break;
0111 }
0112 }
0113
0114 size_t aStartLinePos = myBufferPos;
0115 bool isEndLineFound = false;
0116
0117
0118 while (myBufferPos < myBytesLastRead)
0119 {
0120 if (myIsMultilineMode
0121 && myReadBuffer[myBufferPos] == '\\')
0122 {
0123
0124 if (myBufferPos + 1 == myBytesLastRead
0125 || (myBufferPos + 2 == myBytesLastRead
0126 && myReadBuffer[myBufferPos + 1] == '\r'))
0127 {
0128 isMultiline = true;
0129 if (myToPutGapInMultiline)
0130 {
0131 myReadBuffer[myBufferPos] = ' ';
0132 if (myBufferPos + 1 != myBytesLastRead)
0133 {
0134 myReadBuffer[myBufferPos + 1] = ' ';
0135 }
0136 }
0137 }
0138 else if (myReadBuffer[myBufferPos + 1] == '\n'
0139 ||(myReadBuffer[myBufferPos + 1] == '\r'
0140 && myReadBuffer[myBufferPos + 2] == '\n'))
0141 {
0142 size_t aBufferPos = myBufferPos;
0143 myBufferPos = aBufferPos + (myReadBuffer[aBufferPos + 1] == '\r' ? 2 : 1);
0144 if (myToPutGapInMultiline)
0145 {
0146 myReadBuffer[aBufferPos] = ' ';
0147 ++aBufferPos;
0148 }
0149
0150 if (myUseReadBufferLastStr)
0151 {
0152 myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + aBufferPos);
0153 }
0154 else
0155 {
0156 myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + aBufferPos);
0157 myUseReadBufferLastStr = true;
0158 }
0159
0160 aStartLinePos = myBufferPos + 1;
0161 }
0162 }
0163 else if (myReadBuffer[myBufferPos] == '\n')
0164 {
0165 if (!isMultiline)
0166 {
0167 isEndLineFound = true;
0168 }
0169 else if (myBufferPos == 1 && myReadBuffer[0] == '\r')
0170 {
0171 myReadBufferLastStr.erase (myReadBufferLastStr.end() - 1);
0172 aStartLinePos += 2;
0173 isMultiline = false;
0174 }
0175 else if (myBufferPos == 0)
0176 {
0177 aStartLinePos += 1;
0178 if (myReadBufferLastStr[myReadBufferLastStr.size() - 1] == '\\')
0179 {
0180 myReadBufferLastStr.erase (myReadBufferLastStr.end() - 1);
0181 }
0182 else
0183 {
0184 myReadBufferLastStr.erase (myReadBufferLastStr.end() - 2, myReadBufferLastStr.end());
0185 }
0186 isMultiline = false;
0187 }
0188 }
0189
0190 ++myBufferPos;
0191
0192 if (isEndLineFound) break;
0193 }
0194
0195 if (isEndLineFound)
0196 {
0197 if (myUseReadBufferLastStr)
0198 {
0199
0200 myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
0201 myUseReadBufferLastStr = false;
0202 theLineLength = myReadBufferLastStr.size();
0203 aResultLine = &myReadBufferLastStr.front();
0204 }
0205 else
0206 {
0207 if (myReadBufferLastStr.size() > 0)
0208 {
0209 myReadBufferLastStr.clear();
0210 }
0211 theLineLength = myBufferPos - aStartLinePos;
0212 aResultLine = &myReadBuffer.front() + aStartLinePos;
0213 }
0214
0215 if (theLineLength > 1 && aResultLine[theLineLength - 2] == '\r')
0216 {
0217 aResultLine[theLineLength - 2] = '\0';
0218 theLineLength -= 2;
0219 }
0220 else
0221 {
0222 aResultLine[theLineLength - 1] = '\0';
0223 theLineLength -= 1;
0224 }
0225 }
0226 else
0227 {
0228
0229 if (aStartLinePos != myBufferPos)
0230 {
0231 if (myUseReadBufferLastStr)
0232 {
0233 myReadBufferLastStr.insert (myReadBufferLastStr.end(), myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
0234 }
0235 else
0236 {
0237 myReadBufferLastStr = std::vector<char>(myReadBuffer.begin() + aStartLinePos, myReadBuffer.begin() + myBufferPos);
0238 myUseReadBufferLastStr = true;
0239 }
0240 }
0241 }
0242 }
0243 return aResultLine;
0244 }
0245
0246
0247
0248
0249
0250
0251
0252
0253 bool IsMultilineMode() const { return myIsMultilineMode; }
0254
0255
0256
0257
0258
0259
0260
0261 bool ToPutGapInMultiline() const { return myToPutGapInMultiline; }
0262
0263
0264
0265
0266 void SetMultilineMode (bool theMultilineMode,
0267 bool theToPutGap = true)
0268 {
0269 myIsMultilineMode = theMultilineMode;
0270 myToPutGapInMultiline = theToPutGap;
0271 }
0272
0273 protected:
0274
0275
0276
0277 bool readStream (std::istream& theStream,
0278 size_t theLen,
0279 size_t& theReadLen)
0280 {
0281 theReadLen = (size_t )theStream.read (&myReadBuffer.front(), theLen).gcount();
0282 return !theStream.bad();
0283 }
0284
0285
0286
0287 bool readStream (FILE* theStream,
0288 size_t theLen,
0289 size_t& theReadLen)
0290 {
0291 theReadLen = ::fread (&myReadBuffer.front(), 1, theLen, theStream);
0292 return ::ferror (theStream) == 0;
0293 }
0294
0295 protected:
0296
0297 std::vector<char> myReadBuffer;
0298 std::vector<char> myReadBufferLastStr;
0299 bool myUseReadBufferLastStr;
0300 bool myIsMultilineMode;
0301 bool myToPutGapInMultiline;
0302 size_t myBufferPos;
0303 size_t myBytesLastRead;
0304 };
0305
0306 #endif