1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #include <precomp.h> 23 #include <tools/tkpchars.hxx> 24 25 // NOT FULLY DECLARED SERVICES 26 #include <cosv/bstream.hxx> 27 #include <cosv/x.hxx> 28 29 30 31 CharacterSource::CharacterSource() 32 : dpSource(new char[2]), 33 nSourceSize(0), 34 nCurPos(0), 35 nLastCut(0), 36 nLastTokenStart(0), 37 cCharAtLastCut(0) 38 { 39 dpSource[nSourceSize] = NULCH; 40 dpSource[nSourceSize+1] = NULCH; 41 } 42 43 CharacterSource::~CharacterSource() 44 { 45 delete [] dpSource; 46 } 47 48 void 49 CharacterSource::LoadText(csv::bstream & io_rSource) 50 { 51 if (dpSource != 0) 52 delete [] dpSource; 53 54 io_rSource.seek(0, csv::end); 55 nSourceSize = intt(io_rSource.position()); 56 io_rSource.seek(0); 57 58 dpSource = new char[nSourceSize+1]; 59 60 intt nCount = (intt) io_rSource.read(dpSource,nSourceSize); 61 if (nCount != nSourceSize) 62 throw csv::X_Default("IO-Error: Could not load file completely."); 63 64 dpSource[nSourceSize] = NULCH; 65 66 BeginSource(); 67 } 68 69 /// KORR_FUTURE: So far, this works only when tokens do not cross inserted text boundaries. 70 void 71 CharacterSource::InsertTextAtCurPos( const char * i_sText2Insert ) 72 { 73 if ( i_sText2Insert == 0 ? true : strlen(i_sText2Insert) == 0 ) 74 return; 75 76 aSourcesStack.push( S_SourceState( 77 dpSource, 78 nSourceSize, 79 nCurPos, 80 nLastCut, 81 nLastTokenStart, 82 cCharAtLastCut ) ); 83 84 nSourceSize = strlen(i_sText2Insert); 85 dpSource = new char[nSourceSize+1]; 86 strcpy( dpSource, i_sText2Insert); // SAFE STRCPY (#100211# - checked) 87 88 BeginSource(); 89 } 90 91 const char * 92 CharacterSource::CutToken() 93 { 94 dpSource[nLastCut] = cCharAtLastCut; 95 nLastTokenStart = nLastCut; 96 nLastCut = CurPos(); 97 cCharAtLastCut = dpSource[nLastCut]; 98 dpSource[nLastCut] = NULCH; 99 100 return &dpSource[nLastTokenStart]; 101 } 102 103 void 104 CharacterSource::BeginSource() 105 { 106 nCurPos = 0; 107 nLastCut = 0; 108 nLastTokenStart = 0; 109 cCharAtLastCut = dpSource[nLastCut]; 110 dpSource[nLastCut] = NULCH; 111 } 112 113 // KORR_FUTURE: So far, this works only when tokens do not cross inserted text boundaries. 114 char 115 CharacterSource::MoveOn_OverStack() 116 { 117 while ( aSourcesStack.size() > 0 AND nCurPos >= nSourceSize-1 ) 118 { 119 S_SourceState & aState = aSourcesStack.top(); 120 delete [] dpSource; 121 122 dpSource = aState.dpSource; 123 nSourceSize = aState.nSourceSize; 124 nCurPos = aState.nCurPos; 125 nLastCut = aState.nLastCut; 126 nLastTokenStart = aState.nLastTokenStart; 127 cCharAtLastCut = aState.cCharAtLastCut; 128 129 aSourcesStack.pop(); 130 } 131 132 if ( nLastCut < nCurPos ) 133 CutToken(); 134 135 return CurChar(); 136 } 137 138 CharacterSource:: 139 S_SourceState::S_SourceState( DYN char * dpSource_, 140 intt nSourceSize_, 141 intt nCurPos_, 142 intt nLastCut_, 143 intt nLastTokenStart_, 144 char cCharAtLastCut_ ) 145 : dpSource(dpSource_), 146 nSourceSize(nSourceSize_), 147 nCurPos(nCurPos_), 148 nLastCut(nLastCut_), 149 nLastTokenStart(nLastTokenStart_), 150 cCharAtLastCut(cCharAtLastCut_) 151 { 152 } 153 154