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 CharacterSource::CharacterSource() 30 : dpSource(new char[2]), 31 nSourceSize(0), 32 nCurPos(0), 33 nLastCut(0), 34 nLastTokenStart(0), 35 cCharAtLastCut(0) 36 { 37 dpSource[nSourceSize] = NULCH; 38 dpSource[nSourceSize+1] = NULCH; 39 } 40 41 CharacterSource::~CharacterSource() 42 { 43 delete [] dpSource; 44 } 45 46 void 47 CharacterSource::LoadText(csv::bstream & io_rSource) 48 { 49 if (dpSource != 0) 50 delete [] dpSource; 51 52 io_rSource.seek(0, csv::end); 53 nSourceSize = intt(io_rSource.position()); 54 io_rSource.seek(0); 55 56 dpSource = new char[nSourceSize+1]; 57 58 intt nCount = (intt) io_rSource.read(dpSource,nSourceSize); 59 if (nCount != nSourceSize) 60 throw csv::X_Default("IO-Error: Could not load file completely."); 61 62 dpSource[nSourceSize] = NULCH; 63 64 BeginSource(); 65 } 66 67 // KORR_FUTURE: So far, this works only when tokens do not cross inserted text boundaries. 68 void 69 CharacterSource::InsertTextAtCurPos( const char * i_sText2Insert ) 70 { 71 if ( i_sText2Insert == 0 ? true : strlen(i_sText2Insert) == 0 ) 72 return; 73 74 aSourcesStack.push( S_SourceState( 75 dpSource, 76 nSourceSize, 77 nCurPos, 78 nLastCut, 79 nLastTokenStart, 80 cCharAtLastCut ) ); 81 82 nSourceSize = strlen(i_sText2Insert); 83 dpSource = new char[nSourceSize+1]; 84 strcpy( dpSource, i_sText2Insert); // SAFE STRCPY (#100211# - checked) 85 86 BeginSource(); 87 } 88 89 const char * 90 CharacterSource::CutToken() 91 { 92 dpSource[nLastCut] = cCharAtLastCut; 93 nLastTokenStart = nLastCut; 94 nLastCut = CurPos(); 95 cCharAtLastCut = dpSource[nLastCut]; 96 dpSource[nLastCut] = NULCH; 97 98 return &dpSource[nLastTokenStart]; 99 } 100 101 void 102 CharacterSource::BeginSource() 103 { 104 nCurPos = 0; 105 nLastCut = 0; 106 nLastTokenStart = 0; 107 cCharAtLastCut = dpSource[nLastCut]; 108 dpSource[nLastCut] = NULCH; 109 } 110 111 // KORR_FUTURE: So far, this works only when tokens do not cross inserted text boundaries. 112 char 113 CharacterSource::MoveOn_OverStack() 114 { 115 while ( aSourcesStack.size() > 0 AND nCurPos >= nSourceSize-1 ) 116 { 117 S_SourceState & aState = aSourcesStack.top(); 118 delete [] dpSource; 119 120 dpSource = aState.dpSource; 121 nSourceSize = aState.nSourceSize; 122 nCurPos = aState.nCurPos; 123 nLastCut = aState.nLastCut; 124 nLastTokenStart = aState.nLastTokenStart; 125 cCharAtLastCut = aState.cCharAtLastCut; 126 127 aSourcesStack.pop(); 128 } 129 130 if ( nLastCut < nCurPos ) 131 CutToken(); 132 133 return CurChar(); 134 } 135 136 CharacterSource:: 137 S_SourceState::S_SourceState( DYN char * dpSource_, 138 intt nSourceSize_, 139 intt nCurPos_, 140 intt nLastCut_, 141 intt nLastTokenStart_, 142 char cCharAtLastCut_ ) 143 : dpSource(dpSource_), 144 nSourceSize(nSourceSize_), 145 nCurPos(nCurPos_), 146 nLastCut(nLastCut_), 147 nLastTokenStart(nLastTokenStart_), 148 cCharAtLastCut(cCharAtLastCut_) 149 { 150 } 151 152 /* vim: set noet sw=4 ts=4: */ 153