xref: /AOO41X/main/connectivity/source/drivers/dbase/DNoException.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
30*cdf0e10cSrcweir #include "dbase/DTable.hxx"
31*cdf0e10cSrcweir #include "dbase/DIndex.hxx"
32*cdf0e10cSrcweir #include "dbase/dindexnode.hxx"
33*cdf0e10cSrcweir #include <tools/debug.hxx>
34*cdf0e10cSrcweir #include "diagnose_ex.h"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <sal/types.h>
37*cdf0e10cSrcweir #include <algorithm>
38*cdf0e10cSrcweir #include <rtl/logfile.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir using namespace connectivity;
41*cdf0e10cSrcweir using namespace connectivity::dbase;
42*cdf0e10cSrcweir using namespace com::sun::star::uno;
43*cdf0e10cSrcweir using namespace com::sun::star::sdbc;
44*cdf0e10cSrcweir //------------------------------------------------------------------
45*cdf0e10cSrcweir sal_Bool ODbaseTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos)
46*cdf0e10cSrcweir {
47*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::seekRow" );
48*cdf0e10cSrcweir 	// ----------------------------------------------------------
49*cdf0e10cSrcweir 	// Positionierung vorbereiten:
50*cdf0e10cSrcweir 	OSL_ENSURE(m_pFileStream,"ODbaseTable::seekRow: FileStream is NULL!");
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 	sal_uInt32  nNumberOfRecords = (sal_uInt32)m_aHeader.db_anz;
53*cdf0e10cSrcweir 	sal_uInt32 nTempPos = m_nFilePos;
54*cdf0e10cSrcweir 	m_nFilePos = nCurPos;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir 	switch(eCursorPosition)
57*cdf0e10cSrcweir 	{
58*cdf0e10cSrcweir 		case IResultSetHelper::NEXT:
59*cdf0e10cSrcweir 			++m_nFilePos;
60*cdf0e10cSrcweir 			break;
61*cdf0e10cSrcweir 		case IResultSetHelper::PRIOR:
62*cdf0e10cSrcweir 			if (m_nFilePos > 0)
63*cdf0e10cSrcweir 				--m_nFilePos;
64*cdf0e10cSrcweir 			break;
65*cdf0e10cSrcweir 		case IResultSetHelper::FIRST:
66*cdf0e10cSrcweir 			m_nFilePos = 1;
67*cdf0e10cSrcweir 			break;
68*cdf0e10cSrcweir 		case IResultSetHelper::LAST:
69*cdf0e10cSrcweir 			m_nFilePos = nNumberOfRecords;
70*cdf0e10cSrcweir 			break;
71*cdf0e10cSrcweir 		case IResultSetHelper::RELATIVE:
72*cdf0e10cSrcweir 			m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L
73*cdf0e10cSrcweir 							: (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset);
74*cdf0e10cSrcweir 			break;
75*cdf0e10cSrcweir 		case IResultSetHelper::ABSOLUTE:
76*cdf0e10cSrcweir 		case IResultSetHelper::BOOKMARK:
77*cdf0e10cSrcweir 			m_nFilePos = (sal_uInt32)nOffset;
78*cdf0e10cSrcweir 			break;
79*cdf0e10cSrcweir 	}
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 	if (m_nFilePos > (sal_Int32)nNumberOfRecords)
82*cdf0e10cSrcweir 		m_nFilePos = (sal_Int32)nNumberOfRecords + 1;
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 	if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1)
85*cdf0e10cSrcweir 		goto Error;
86*cdf0e10cSrcweir 	else
87*cdf0e10cSrcweir 	{
88*cdf0e10cSrcweir 		sal_uInt16 nEntryLen = m_aHeader.db_slng;
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir 		OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
91*cdf0e10cSrcweir 		sal_Int32 nPos = m_aHeader.db_kopf + (sal_Int32)(m_nFilePos-1) * nEntryLen;
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 		sal_uIntPtr nLen = m_pFileStream->Seek(nPos);
94*cdf0e10cSrcweir 		if (m_pFileStream->GetError() != ERRCODE_NONE)
95*cdf0e10cSrcweir 			goto Error;
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 		nLen = m_pFileStream->Read((char*)m_pBuffer, nEntryLen);
98*cdf0e10cSrcweir 		if (m_pFileStream->GetError() != ERRCODE_NONE)
99*cdf0e10cSrcweir 			goto Error;
100*cdf0e10cSrcweir 	}
101*cdf0e10cSrcweir 	goto End;
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir Error:
104*cdf0e10cSrcweir 	switch(eCursorPosition)
105*cdf0e10cSrcweir 	{
106*cdf0e10cSrcweir 		case IResultSetHelper::PRIOR:
107*cdf0e10cSrcweir 		case IResultSetHelper::FIRST:
108*cdf0e10cSrcweir 			m_nFilePos = 0;
109*cdf0e10cSrcweir 			break;
110*cdf0e10cSrcweir 		case IResultSetHelper::LAST:
111*cdf0e10cSrcweir 		case IResultSetHelper::NEXT:
112*cdf0e10cSrcweir 		case IResultSetHelper::ABSOLUTE:
113*cdf0e10cSrcweir 		case IResultSetHelper::RELATIVE:
114*cdf0e10cSrcweir 			if (nOffset > 0)
115*cdf0e10cSrcweir 				m_nFilePos = nNumberOfRecords + 1;
116*cdf0e10cSrcweir 			else if (nOffset < 0)
117*cdf0e10cSrcweir 				m_nFilePos = 0;
118*cdf0e10cSrcweir 			break;
119*cdf0e10cSrcweir 		case IResultSetHelper::BOOKMARK:
120*cdf0e10cSrcweir 			m_nFilePos = nTempPos;	 // vorherige Position
121*cdf0e10cSrcweir 	}
122*cdf0e10cSrcweir 	//	aStatus.Set(SDB_STAT_NO_DATA_FOUND);
123*cdf0e10cSrcweir 	return sal_False;
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir End:
126*cdf0e10cSrcweir 	nCurPos = m_nFilePos;
127*cdf0e10cSrcweir 	return sal_True;
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir // -----------------------------------------------------------------------------
130*cdf0e10cSrcweir sal_Bool ODbaseTable::ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable)
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ReadMemo" );
133*cdf0e10cSrcweir 	sal_Bool bIsText = sal_True;
134*cdf0e10cSrcweir 	//	SdbConnection* pConnection = GetConnection();
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir 	m_pMemoStream->Seek(nBlockNo * m_aMemoHeader.db_size);
137*cdf0e10cSrcweir 	switch (m_aMemoHeader.db_typ)
138*cdf0e10cSrcweir 	{
139*cdf0e10cSrcweir 		case MemodBaseIII: // dBase III-Memofeld, endet mit Ctrl-Z
140*cdf0e10cSrcweir 		{
141*cdf0e10cSrcweir 			const char cEOF = (char) 0x1a;
142*cdf0e10cSrcweir 			ByteString aBStr;
143*cdf0e10cSrcweir 			static char aBuf[514];
144*cdf0e10cSrcweir 			aBuf[512] = 0;			// sonst kann der Zufall uebel mitspielen
145*cdf0e10cSrcweir 			sal_Bool bReady = sal_False;
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 			do
148*cdf0e10cSrcweir 			{
149*cdf0e10cSrcweir 				m_pMemoStream->Read(&aBuf,512);
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir 				sal_uInt16 i = 0;
152*cdf0e10cSrcweir 				while (aBuf[i] != cEOF && ++i < 512)
153*cdf0e10cSrcweir 					;
154*cdf0e10cSrcweir 				bReady = aBuf[i] == cEOF;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 				aBuf[i] = 0;
157*cdf0e10cSrcweir 				aBStr += aBuf;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 			} while (!bReady && !m_pMemoStream->IsEof() && aBStr.Len() < STRING_MAXLEN);
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 			::rtl::OUString aStr(aBStr.GetBuffer(), aBStr.Len(),getConnection()->getTextEncoding());
162*cdf0e10cSrcweir 			aVariable = aStr;
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 		} break;
165*cdf0e10cSrcweir 		case MemoFoxPro:
166*cdf0e10cSrcweir 		case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe
167*cdf0e10cSrcweir 		{
168*cdf0e10cSrcweir 			char sHeader[4];
169*cdf0e10cSrcweir 			m_pMemoStream->Read(sHeader,4);
170*cdf0e10cSrcweir 			// Foxpro stores text and binary data
171*cdf0e10cSrcweir 			if (m_aMemoHeader.db_typ == MemoFoxPro)
172*cdf0e10cSrcweir 			{
173*cdf0e10cSrcweir 				if (((sal_uInt8)sHeader[0]) != 0 || ((sal_uInt8)sHeader[1]) != 0 || ((sal_uInt8)sHeader[2]) != 0)
174*cdf0e10cSrcweir 				{
175*cdf0e10cSrcweir //					String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID));
176*cdf0e10cSrcweir //					aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName());
177*cdf0e10cSrcweir //					aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO));
178*cdf0e10cSrcweir //					aStatus.Set(SDB_STAT_ERROR,
179*cdf0e10cSrcweir //							String::CreateFromAscii("01000"),
180*cdf0e10cSrcweir //							aStatus.CreateErrorMessage(aText),
181*cdf0e10cSrcweir //							0, String() );
182*cdf0e10cSrcweir 					return sal_False;
183*cdf0e10cSrcweir 				}
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir 				bIsText = sHeader[3] != 0;
186*cdf0e10cSrcweir 			}
187*cdf0e10cSrcweir 			else if (((sal_uInt8)sHeader[0]) != 0xFF || ((sal_uInt8)sHeader[1]) != 0xFF || ((sal_uInt8)sHeader[2]) != 0x08)
188*cdf0e10cSrcweir 			{
189*cdf0e10cSrcweir //				String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID));
190*cdf0e10cSrcweir //				aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName());
191*cdf0e10cSrcweir //				aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO));
192*cdf0e10cSrcweir //				aStatus.Set(SDB_STAT_ERROR,
193*cdf0e10cSrcweir //						String::CreateFromAscii("01000"),
194*cdf0e10cSrcweir //						aStatus.CreateErrorMessage(aText),
195*cdf0e10cSrcweir //						0, String() );
196*cdf0e10cSrcweir 				return sal_False;
197*cdf0e10cSrcweir 			}
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 			sal_uInt32 nLength;
200*cdf0e10cSrcweir 			(*m_pMemoStream) >> nLength;
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 			if (m_aMemoHeader.db_typ == MemodBaseIV)
203*cdf0e10cSrcweir 				nLength -= 8;
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 			//	char cChar;
206*cdf0e10cSrcweir 			::rtl::OUString aStr;
207*cdf0e10cSrcweir 			while ( nLength > STRING_MAXLEN )
208*cdf0e10cSrcweir 			{
209*cdf0e10cSrcweir 				ByteString aBStr;
210*cdf0e10cSrcweir 				aBStr.Expand(STRING_MAXLEN);
211*cdf0e10cSrcweir 				m_pMemoStream->Read(aBStr.AllocBuffer(STRING_MAXLEN),STRING_MAXLEN);
212*cdf0e10cSrcweir 				aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding());
213*cdf0e10cSrcweir 				nLength -= STRING_MAXLEN;
214*cdf0e10cSrcweir 			}
215*cdf0e10cSrcweir 			if ( nLength > 0 )
216*cdf0e10cSrcweir 			{
217*cdf0e10cSrcweir 				ByteString aBStr;
218*cdf0e10cSrcweir 				aBStr.Expand(static_cast<xub_StrLen>(nLength));
219*cdf0e10cSrcweir 				m_pMemoStream->Read(aBStr.AllocBuffer(static_cast<xub_StrLen>(nLength)),nLength);
220*cdf0e10cSrcweir 				//	aBStr.ReleaseBufferAccess();
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir 				aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding());
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir 			}
225*cdf0e10cSrcweir 			if ( aStr.getLength() )
226*cdf0e10cSrcweir 				aVariable = aStr;
227*cdf0e10cSrcweir 		}
228*cdf0e10cSrcweir 	}
229*cdf0e10cSrcweir 	return sal_True;
230*cdf0e10cSrcweir }
231*cdf0e10cSrcweir // -----------------------------------------------------------------------------
232*cdf0e10cSrcweir void ODbaseTable::AllocBuffer()
233*cdf0e10cSrcweir {
234*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::AllocBuffer" );
235*cdf0e10cSrcweir 	sal_uInt16 nSize = m_aHeader.db_slng;
236*cdf0e10cSrcweir 	OSL_ENSURE(nSize > 0, "Size too small");
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 	if (m_nBufferSize != nSize)
239*cdf0e10cSrcweir 	{
240*cdf0e10cSrcweir 		delete[] m_pBuffer;
241*cdf0e10cSrcweir 		m_pBuffer = NULL;
242*cdf0e10cSrcweir 	}
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 	// Falls noch kein Puffer vorhanden: allozieren:
245*cdf0e10cSrcweir 	if (m_pBuffer == NULL && nSize > 0)
246*cdf0e10cSrcweir 	{
247*cdf0e10cSrcweir 		m_nBufferSize = nSize;
248*cdf0e10cSrcweir 		m_pBuffer		= new sal_uInt8[m_nBufferSize+1];
249*cdf0e10cSrcweir 	}
250*cdf0e10cSrcweir }
251*cdf0e10cSrcweir // -----------------------------------------------------------------------------
252*cdf0e10cSrcweir sal_Bool ODbaseTable::WriteBuffer()
253*cdf0e10cSrcweir {
254*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::WriteBuffer" );
255*cdf0e10cSrcweir 	OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position");
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir 	// Auf gewuenschten Record positionieren:
258*cdf0e10cSrcweir 	long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng;
259*cdf0e10cSrcweir 	m_pFileStream->Seek(nPos);
260*cdf0e10cSrcweir 	return m_pFileStream->Write((char*) m_pBuffer, m_aHeader.db_slng) > 0;
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir // -----------------------------------------------------------------------------
263*cdf0e10cSrcweir sal_Int32 ODbaseTable::getCurrentLastPos() const
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getCurrentLastPos" );
266*cdf0e10cSrcweir 	return m_aHeader.db_anz;
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir // -----------------------------------------------------------------------------
269*cdf0e10cSrcweir //==================================================================
270*cdf0e10cSrcweir // ONDXNode
271*cdf0e10cSrcweir //==================================================================
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir //------------------------------------------------------------------
274*cdf0e10cSrcweir void ONDXNode::Read(SvStream &rStream, ODbaseIndex& rIndex)
275*cdf0e10cSrcweir {
276*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Read" );
277*cdf0e10cSrcweir 	rStream >> aKey.nRecord; // schluessel
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir 	if (rIndex.getHeader().db_keytype)
280*cdf0e10cSrcweir 	{
281*cdf0e10cSrcweir 		double aDbl;
282*cdf0e10cSrcweir 		rStream >> aDbl;
283*cdf0e10cSrcweir 		aKey = ONDXKey(aDbl,aKey.nRecord);
284*cdf0e10cSrcweir 	}
285*cdf0e10cSrcweir 	else
286*cdf0e10cSrcweir 	{
287*cdf0e10cSrcweir 		ByteString aBuf;
288*cdf0e10cSrcweir 		sal_uInt16 nLen = rIndex.getHeader().db_keylen;
289*cdf0e10cSrcweir 		char* pStr = aBuf.AllocBuffer(nLen+1);
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 		rStream.Read(pStr,nLen);
292*cdf0e10cSrcweir 		pStr[nLen] = 0;
293*cdf0e10cSrcweir 		aBuf.ReleaseBufferAccess();
294*cdf0e10cSrcweir 		aBuf.EraseTrailingChars();
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir 		//	aKey = ONDXKey((aBuf,rIndex.GetDBFConnection()->GetCharacterSet()) ,aKey.nRecord);
297*cdf0e10cSrcweir 		aKey = ONDXKey(::rtl::OUString(aBuf.GetBuffer(),aBuf.Len(),rIndex.m_pTable->getConnection()->getTextEncoding()) ,aKey.nRecord);
298*cdf0e10cSrcweir 	}
299*cdf0e10cSrcweir 	rStream >> aChild;
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir union
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir 	double aDbl;
305*cdf0e10cSrcweir 	char   aData[128];
306*cdf0e10cSrcweir } aNodeData;
307*cdf0e10cSrcweir //------------------------------------------------------------------
308*cdf0e10cSrcweir void ONDXNode::Write(SvStream &rStream, const ONDXPage& rPage) const
309*cdf0e10cSrcweir {
310*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Write" );
311*cdf0e10cSrcweir 	const ODbaseIndex& rIndex = rPage.GetIndex();
312*cdf0e10cSrcweir 	if (!rIndex.isUnique() || rPage.IsLeaf())
313*cdf0e10cSrcweir 		rStream << (sal_uInt32)aKey.nRecord; // schluessel
314*cdf0e10cSrcweir 	else
315*cdf0e10cSrcweir 		rStream << (sal_uInt32)0;	// schluessel
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 	if (rIndex.getHeader().db_keytype) // double
318*cdf0e10cSrcweir 	{
319*cdf0e10cSrcweir 		if (aKey.getValue().isNull())
320*cdf0e10cSrcweir 		{
321*cdf0e10cSrcweir 			memset(aNodeData.aData,0,rIndex.getHeader().db_keylen);
322*cdf0e10cSrcweir 			rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen);
323*cdf0e10cSrcweir 		}
324*cdf0e10cSrcweir 		else
325*cdf0e10cSrcweir 			rStream << (double) aKey.getValue();
326*cdf0e10cSrcweir 	}
327*cdf0e10cSrcweir 	else
328*cdf0e10cSrcweir 	{
329*cdf0e10cSrcweir 		memset(aNodeData.aData,0x20,rIndex.getHeader().db_keylen);
330*cdf0e10cSrcweir 		if (!aKey.getValue().isNull())
331*cdf0e10cSrcweir 		{
332*cdf0e10cSrcweir 			::rtl::OUString sValue = aKey.getValue();
333*cdf0e10cSrcweir 			ByteString aText(sValue.getStr(), rIndex.m_pTable->getConnection()->getTextEncoding());
334*cdf0e10cSrcweir 			strncpy(aNodeData.aData,aText.GetBuffer(),std::min(rIndex.getHeader().db_keylen, aText.Len()));
335*cdf0e10cSrcweir 		}
336*cdf0e10cSrcweir 		rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen);
337*cdf0e10cSrcweir 	}
338*cdf0e10cSrcweir 	rStream << aChild;
339*cdf0e10cSrcweir }
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir 
342*cdf0e10cSrcweir //------------------------------------------------------------------
343*cdf0e10cSrcweir ONDXPagePtr& ONDXNode::GetChild(ODbaseIndex* pIndex, ONDXPage* pParent)
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::GetChild" );
346*cdf0e10cSrcweir 	if (!aChild.Is() && pIndex)
347*cdf0e10cSrcweir 	{
348*cdf0e10cSrcweir 		aChild = pIndex->CreatePage(aChild.GetPagePos(),pParent,aChild.HasPage());
349*cdf0e10cSrcweir 	}
350*cdf0e10cSrcweir 	return aChild;
351*cdf0e10cSrcweir }
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir //==================================================================
354*cdf0e10cSrcweir // ONDXKey
355*cdf0e10cSrcweir //==================================================================
356*cdf0e10cSrcweir //------------------------------------------------------------------
357*cdf0e10cSrcweir sal_Bool ONDXKey::IsText(sal_Int32 eType)
358*cdf0e10cSrcweir {
359*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::IsText" );
360*cdf0e10cSrcweir 	return eType == DataType::VARCHAR || eType == DataType::CHAR;
361*cdf0e10cSrcweir }
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir //------------------------------------------------------------------
364*cdf0e10cSrcweir StringCompare ONDXKey::Compare(const ONDXKey& rKey) const
365*cdf0e10cSrcweir {
366*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::Compare" );
367*cdf0e10cSrcweir 	//	DBG_ASSERT(is(), "Falscher Indexzugriff");
368*cdf0e10cSrcweir 	StringCompare eResult;
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir 	if (getValue().isNull())
371*cdf0e10cSrcweir 	{
372*cdf0e10cSrcweir 		if (rKey.getValue().isNull() || (rKey.IsText(getDBType()) && !rKey.getValue().getString().getLength()))
373*cdf0e10cSrcweir 			eResult = COMPARE_EQUAL;
374*cdf0e10cSrcweir 		else
375*cdf0e10cSrcweir 			eResult = COMPARE_LESS;
376*cdf0e10cSrcweir 	}
377*cdf0e10cSrcweir 	else if (rKey.getValue().isNull())
378*cdf0e10cSrcweir 	{
379*cdf0e10cSrcweir 		if (getValue().isNull() || (IsText(getDBType()) && !getValue().getString().getLength()))
380*cdf0e10cSrcweir 			eResult = COMPARE_EQUAL;
381*cdf0e10cSrcweir 		else
382*cdf0e10cSrcweir 			eResult = COMPARE_GREATER;
383*cdf0e10cSrcweir 	}
384*cdf0e10cSrcweir 	else if (IsText(getDBType()))
385*cdf0e10cSrcweir 	{
386*cdf0e10cSrcweir 		sal_Int32 nRes = getValue().getString().compareTo(rKey.getValue());
387*cdf0e10cSrcweir 		eResult = (nRes > 0) ? COMPARE_GREATER : (nRes == 0) ? COMPARE_EQUAL : COMPARE_LESS;
388*cdf0e10cSrcweir 	}
389*cdf0e10cSrcweir 	else
390*cdf0e10cSrcweir 	{
391*cdf0e10cSrcweir 		double m = getValue(),n = rKey.getValue();
392*cdf0e10cSrcweir 		eResult = (m > n) ? COMPARE_GREATER : (n == m) ? COMPARE_EQUAL : COMPARE_LESS;
393*cdf0e10cSrcweir 	}
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir 	// Record vergleich, wenn Index !Unique
396*cdf0e10cSrcweir 	if (eResult == COMPARE_EQUAL && nRecord && rKey.nRecord)
397*cdf0e10cSrcweir 		eResult = (nRecord > rKey.nRecord) ? COMPARE_GREATER :
398*cdf0e10cSrcweir 				  (nRecord == rKey.nRecord) ? COMPARE_EQUAL : COMPARE_LESS;
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir 	return eResult;
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir // -----------------------------------------------------------------------------
403*cdf0e10cSrcweir void ONDXKey::setValue(const ORowSetValue& _rVal)
404*cdf0e10cSrcweir {
405*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::setValue" );
406*cdf0e10cSrcweir 	xValue = _rVal;
407*cdf0e10cSrcweir }
408*cdf0e10cSrcweir // -----------------------------------------------------------------------------
409*cdf0e10cSrcweir const ORowSetValue& ONDXKey::getValue() const
410*cdf0e10cSrcweir {
411*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::getValue" );
412*cdf0e10cSrcweir 	return xValue;
413*cdf0e10cSrcweir }
414*cdf0e10cSrcweir // -----------------------------------------------------------------------------
415*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPagePtr& rPage)
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir 	rStream >> rPage.nPagePos;
418*cdf0e10cSrcweir 	return rStream;
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir // -----------------------------------------------------------------------------
421*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPagePtr& rPage)
422*cdf0e10cSrcweir {
423*cdf0e10cSrcweir 	rStream << rPage.nPagePos;
424*cdf0e10cSrcweir 	return rStream;
425*cdf0e10cSrcweir }
426*cdf0e10cSrcweir // -----------------------------------------------------------------------------
427*cdf0e10cSrcweir //==================================================================
428*cdf0e10cSrcweir // ONDXPagePtr
429*cdf0e10cSrcweir //==================================================================
430*cdf0e10cSrcweir //------------------------------------------------------------------
431*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(const ONDXPagePtr& rRef)
432*cdf0e10cSrcweir 			  :ONDXPageRef(rRef)
433*cdf0e10cSrcweir 			  ,nPagePos(rRef.nPagePos)
434*cdf0e10cSrcweir {
435*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" );
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir //------------------------------------------------------------------
439*cdf0e10cSrcweir ONDXPagePtr::ONDXPagePtr(ONDXPage* pRefPage)
440*cdf0e10cSrcweir 			  :ONDXPageRef(pRefPage)
441*cdf0e10cSrcweir 			  ,nPagePos(0)
442*cdf0e10cSrcweir {
443*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" );
444*cdf0e10cSrcweir 	if (pRefPage)
445*cdf0e10cSrcweir 		nPagePos = pRefPage->GetPagePos();
446*cdf0e10cSrcweir }
447*cdf0e10cSrcweir //------------------------------------------------------------------
448*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator=(const ONDXPagePtr& rRef)
449*cdf0e10cSrcweir {
450*cdf0e10cSrcweir 	ONDXPageRef::operator=(rRef);
451*cdf0e10cSrcweir 	nPagePos = rRef.nPagePos;
452*cdf0e10cSrcweir 	return *this;
453*cdf0e10cSrcweir }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir //------------------------------------------------------------------
456*cdf0e10cSrcweir ONDXPagePtr& ONDXPagePtr::operator= (ONDXPage* pRef)
457*cdf0e10cSrcweir {
458*cdf0e10cSrcweir 	ONDXPageRef::operator=(pRef);
459*cdf0e10cSrcweir 	nPagePos = (pRef) ? pRef->GetPagePos() : 0;
460*cdf0e10cSrcweir 	return *this;
461*cdf0e10cSrcweir }
462*cdf0e10cSrcweir // -----------------------------------------------------------------------------
463*cdf0e10cSrcweir static sal_uInt32 nValue;
464*cdf0e10cSrcweir //------------------------------------------------------------------
465*cdf0e10cSrcweir SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPage& rPage)
466*cdf0e10cSrcweir {
467*cdf0e10cSrcweir 	rStream.Seek(rPage.GetPagePos() * 512);
468*cdf0e10cSrcweir 	rStream >> nValue >> rPage.aChild;
469*cdf0e10cSrcweir 	rPage.nCount = sal_uInt16(nValue);
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir //	DBG_ASSERT(rPage.nCount && rPage.nCount < rPage.GetIndex().GetMaxNodes(), "Falscher Count");
472*cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < rPage.nCount; i++)
473*cdf0e10cSrcweir 		rPage[i].Read(rStream, rPage.GetIndex());
474*cdf0e10cSrcweir 	return rStream;
475*cdf0e10cSrcweir }
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir //------------------------------------------------------------------
478*cdf0e10cSrcweir SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPage& rPage)
479*cdf0e10cSrcweir {
480*cdf0e10cSrcweir 	// Seite existiert noch nicht
481*cdf0e10cSrcweir 	sal_uIntPtr nSize = (rPage.GetPagePos() + 1) * 512;
482*cdf0e10cSrcweir 	if (nSize > rStream.Seek(STREAM_SEEK_TO_END))
483*cdf0e10cSrcweir 	{
484*cdf0e10cSrcweir 		rStream.SetStreamSize(nSize);
485*cdf0e10cSrcweir 		rStream.Seek(rPage.GetPagePos() * 512);
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir 		char aEmptyData[512];
488*cdf0e10cSrcweir 		memset(aEmptyData,0x00,512);
489*cdf0e10cSrcweir 		rStream.Write((sal_uInt8*)aEmptyData,512);
490*cdf0e10cSrcweir 	}
491*cdf0e10cSrcweir 	sal_uIntPtr nCurrentPos = rStream.Seek(rPage.GetPagePos() * 512);
492*cdf0e10cSrcweir     OSL_UNUSED( nCurrentPos );
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir 	nValue = rPage.nCount;
495*cdf0e10cSrcweir 	rStream << nValue << rPage.aChild;
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir 	sal_uInt16 i = 0;
498*cdf0e10cSrcweir 	for (; i < rPage.nCount; i++)
499*cdf0e10cSrcweir 		rPage[i].Write(rStream, rPage);
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir 	// check if we have to fill the stream with '\0'
502*cdf0e10cSrcweir 	if(i < rPage.rIndex.getHeader().db_maxkeys)
503*cdf0e10cSrcweir 	{
504*cdf0e10cSrcweir 		sal_uIntPtr nTell = rStream.Tell() % 512;
505*cdf0e10cSrcweir 		sal_uInt16 nBufferSize = rStream.GetBufferSize();
506*cdf0e10cSrcweir 		sal_uIntPtr nSize = nBufferSize - nTell;
507*cdf0e10cSrcweir 		if ( nSize <= nBufferSize )
508*cdf0e10cSrcweir 		{
509*cdf0e10cSrcweir 			char* pEmptyData = new char[nSize];
510*cdf0e10cSrcweir 			memset(pEmptyData,0x00,nSize);
511*cdf0e10cSrcweir 			rStream.Write((sal_uInt8*)pEmptyData,nSize);
512*cdf0e10cSrcweir 			rStream.Seek(nTell);
513*cdf0e10cSrcweir 			delete [] pEmptyData;
514*cdf0e10cSrcweir 		}
515*cdf0e10cSrcweir 	}
516*cdf0e10cSrcweir 	return rStream;
517*cdf0e10cSrcweir }
518*cdf0e10cSrcweir // -----------------------------------------------------------------------------
519*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
520*cdf0e10cSrcweir //------------------------------------------------------------------
521*cdf0e10cSrcweir void ONDXPage::PrintPage()
522*cdf0e10cSrcweir {
523*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::PrintPage" );
524*cdf0e10cSrcweir 	DBG_TRACE4("\nSDB: -----------Page: %d  Parent: %d  Count: %d  Child: %d-----",
525*cdf0e10cSrcweir 		nPagePos, HasParent() ? aParent->GetPagePos() : 0 ,nCount, aChild.GetPagePos());
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nCount; i++)
528*cdf0e10cSrcweir 	{
529*cdf0e10cSrcweir 		ONDXNode rNode = (*this)[i];
530*cdf0e10cSrcweir 		ONDXKey&  rKey = rNode.GetKey();
531*cdf0e10cSrcweir 		if (!IsLeaf())
532*cdf0e10cSrcweir 			rNode.GetChild(&rIndex, this);
533*cdf0e10cSrcweir 
534*cdf0e10cSrcweir 		if (rKey.getValue().isNull())
535*cdf0e10cSrcweir 		{
536*cdf0e10cSrcweir 			DBG_TRACE2("SDB: [%d,NULL,%d]",rKey.GetRecord(), rNode.GetChild().GetPagePos());
537*cdf0e10cSrcweir 		}
538*cdf0e10cSrcweir 		else if (rIndex.getHeader().db_keytype)
539*cdf0e10cSrcweir 		{
540*cdf0e10cSrcweir 			DBG_TRACE3("SDB: [%d,%f,%d]",rKey.GetRecord(), rKey.getValue().getDouble(),rNode.GetChild().GetPagePos());
541*cdf0e10cSrcweir 		}
542*cdf0e10cSrcweir 		else
543*cdf0e10cSrcweir 		{
544*cdf0e10cSrcweir 			DBG_TRACE3("SDB: [%d,%s,%d]",rKey.GetRecord(), (const char* )ByteString(rKey.getValue().getString().getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()).GetBuffer(),rNode.GetChild().GetPagePos());
545*cdf0e10cSrcweir 		}
546*cdf0e10cSrcweir 	}
547*cdf0e10cSrcweir 	DBG_TRACE("SDB: -----------------------------------------------\n");
548*cdf0e10cSrcweir 	if (!IsLeaf())
549*cdf0e10cSrcweir 	{
550*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
551*cdf0e10cSrcweir 		GetChild(&rIndex)->PrintPage();
552*cdf0e10cSrcweir 		for (sal_uInt16 i = 0; i < nCount; i++)
553*cdf0e10cSrcweir 		{
554*cdf0e10cSrcweir 			ONDXNode rNode = (*this)[i];
555*cdf0e10cSrcweir 			rNode.GetChild(&rIndex,this)->PrintPage();
556*cdf0e10cSrcweir 		}
557*cdf0e10cSrcweir #endif
558*cdf0e10cSrcweir 	}
559*cdf0e10cSrcweir 	DBG_TRACE("SDB: ===============================================\n");
560*cdf0e10cSrcweir }
561*cdf0e10cSrcweir #endif
562*cdf0e10cSrcweir // -----------------------------------------------------------------------------
563*cdf0e10cSrcweir sal_Bool ONDXPage::IsFull() const
564*cdf0e10cSrcweir {
565*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::IsFull" );
566*cdf0e10cSrcweir 	return Count() == rIndex.getHeader().db_maxkeys;
567*cdf0e10cSrcweir }
568*cdf0e10cSrcweir // -----------------------------------------------------------------------------
569*cdf0e10cSrcweir //------------------------------------------------------------------
570*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXKey& rSearch)
571*cdf0e10cSrcweir {
572*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" );
573*cdf0e10cSrcweir 	// binare Suche spaeter
574*cdf0e10cSrcweir 	sal_uInt16 i = 0xFFFF;
575*cdf0e10cSrcweir 	while (++i < Count())
576*cdf0e10cSrcweir 		if ((*this)[i].GetKey() == rSearch)
577*cdf0e10cSrcweir 			break;
578*cdf0e10cSrcweir 
579*cdf0e10cSrcweir 	return (i < Count()) ? i : NODE_NOTFOUND;
580*cdf0e10cSrcweir }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir //------------------------------------------------------------------
583*cdf0e10cSrcweir sal_uInt16 ONDXPage::Search(const ONDXPage* pPage)
584*cdf0e10cSrcweir {
585*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" );
586*cdf0e10cSrcweir 	sal_uInt16 i = 0xFFFF;
587*cdf0e10cSrcweir 	while (++i < Count())
588*cdf0e10cSrcweir 		if (((*this)[i]).GetChild() == pPage)
589*cdf0e10cSrcweir 			break;
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	// wenn nicht gefunden, dann wird davon ausgegangen, dass die Seite selbst
592*cdf0e10cSrcweir 	// auf die Page zeigt
593*cdf0e10cSrcweir 	return (i < Count()) ? i : NODE_NOTFOUND;
594*cdf0e10cSrcweir }
595*cdf0e10cSrcweir // -----------------------------------------------------------------------------
596*cdf0e10cSrcweir // laeuft rekursiv
597*cdf0e10cSrcweir void ONDXPage::SearchAndReplace(const ONDXKey& rSearch,
598*cdf0e10cSrcweir 								  ONDXKey& rReplace)
599*cdf0e10cSrcweir {
600*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::SearchAndReplace" );
601*cdf0e10cSrcweir 	OSL_ENSURE(rSearch != rReplace,"Invalid here:rSearch == rReplace");
602*cdf0e10cSrcweir 	if (rSearch != rReplace)
603*cdf0e10cSrcweir 	{
604*cdf0e10cSrcweir 		sal_uInt16 nPos = NODE_NOTFOUND;
605*cdf0e10cSrcweir 		ONDXPage* pPage = this;
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir 		while (pPage && (nPos = pPage->Search(rSearch)) == NODE_NOTFOUND)
608*cdf0e10cSrcweir 			pPage = pPage->aParent;
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir 		if (pPage)
611*cdf0e10cSrcweir 		{
612*cdf0e10cSrcweir 			(*pPage)[nPos].GetKey() = rReplace;
613*cdf0e10cSrcweir 			pPage->SetModified(sal_True);
614*cdf0e10cSrcweir 		}
615*cdf0e10cSrcweir 	}
616*cdf0e10cSrcweir }
617*cdf0e10cSrcweir // -----------------------------------------------------------------------------
618*cdf0e10cSrcweir ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos)
619*cdf0e10cSrcweir {
620*cdf0e10cSrcweir 	DBG_ASSERT(nCount > nPos, "falscher Indexzugriff");
621*cdf0e10cSrcweir 	return ppNodes[nPos];
622*cdf0e10cSrcweir }
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir //------------------------------------------------------------------
625*cdf0e10cSrcweir const ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) const
626*cdf0e10cSrcweir {
627*cdf0e10cSrcweir 	DBG_ASSERT(nCount > nPos, "falscher Indexzugriff");
628*cdf0e10cSrcweir 	return ppNodes[nPos];
629*cdf0e10cSrcweir }
630*cdf0e10cSrcweir // -----------------------------------------------------------------------------
631*cdf0e10cSrcweir void ONDXPage::Remove(sal_uInt16 nPos)
632*cdf0e10cSrcweir {
633*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Remove" );
634*cdf0e10cSrcweir 	DBG_ASSERT(nCount > nPos, "falscher Indexzugriff");
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir 	for (sal_uInt16 i = nPos; i < (nCount-1); i++)
637*cdf0e10cSrcweir 		(*this)[i] = (*this)[i+1];
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir 	nCount--;
640*cdf0e10cSrcweir 	bModified = sal_True;
641*cdf0e10cSrcweir }
642*cdf0e10cSrcweir // -----------------------------------------------------------------------------
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir 
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir 
654