xref: /aoo41x/main/svtools/source/misc/imap2.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include <string.h>
32 // #include <math.h>
33 #include <vcl/svapp.hxx>
34 #include <tools/urlobj.hxx>
35 #ifndef _WRKWIN_HXX //autogen
36 #include <vcl/wrkwin.hxx>
37 #endif
38 #include <sot/formats.hxx>
39 
40 #include "svl/urihelper.hxx"
41 #include <svtools/imap.hxx>
42 #include <svtools/imap.hxx>
43 #include <svtools/imapobj.hxx>
44 #include <svtools/imaprect.hxx>
45 #include <svtools/imapcirc.hxx>
46 #include <svtools/imappoly.hxx>
47 
48 #include <string.h>
49 #include <math.h>
50 
51 #define NOTEOL(c) ((c)!='\0')
52 
53 
54 TYPEINIT0_AUTOFACTORY( ImageMap );
55 
56 
57 /******************************************************************************/
58 /******************************************************************************/
59 
60 
61 /******************************************************************************
62 |*
63 |*
64 |*
65 \******************************************************************************/
66 
67 void IMapObject::AppendCERNCoords( const Point& rPoint100, ByteString& rStr ) const
68 {
69 	const Point	aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
70 
71 	rStr += '(';
72 	rStr += ByteString::CreateFromInt32( aPixPt.X() );
73 	rStr += ',';
74 	rStr += ByteString::CreateFromInt32( aPixPt.Y() );
75 	rStr += ") ";
76 }
77 
78 
79 /******************************************************************************
80 |*
81 |*
82 |*
83 \******************************************************************************/
84 
85 void IMapObject::AppendNCSACoords( const Point& rPoint100, ByteString& rStr ) const
86 {
87 	const Point	aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100, MapMode( MAP_100TH_MM ) ) );
88 
89 	rStr += ByteString::CreateFromInt32( aPixPt.X() );
90 	rStr += ',';
91 	rStr += ByteString::CreateFromInt32( aPixPt.Y() );
92 	rStr += ' ';
93 }
94 
95 
96 /******************************************************************************
97 |*
98 |*
99 |*
100 \******************************************************************************/
101 
102 void IMapObject::AppendCERNURL( ByteString& rStr, const String& rBaseURL ) const
103 {
104     rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
105 }
106 
107 
108 /******************************************************************************
109 |*
110 |*
111 |*
112 \******************************************************************************/
113 
114 void IMapObject::AppendNCSAURL( ByteString& rStr, const String& rBaseURL ) const
115 {
116     rStr += ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), gsl_getSystemTextEncoding() );
117 	rStr += ' ';
118 }
119 
120 
121 /******************************************************************************/
122 /******************************************************************************/
123 
124 
125 /******************************************************************************
126 |*
127 |*
128 |*
129 \******************************************************************************/
130 
131 void IMapRectangleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
132 {
133 	ByteString aStr( "rectangle " );
134 
135 	AppendCERNCoords( aRect.TopLeft(), aStr );
136 	AppendCERNCoords( aRect.BottomRight(), aStr );
137     AppendCERNURL( aStr, rBaseURL );
138 
139 	rOStm.WriteLine( aStr );
140 }
141 
142 
143 /******************************************************************************
144 |*
145 |*
146 |*
147 \******************************************************************************/
148 
149 void IMapRectangleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
150 {
151 	ByteString aStr( "rect " );
152 
153     AppendNCSAURL( aStr, rBaseURL );
154 	AppendNCSACoords( aRect.TopLeft(), aStr );
155 	AppendNCSACoords( aRect.BottomRight(), aStr );
156 
157 	rOStm.WriteLine( aStr );
158 }
159 
160 
161 /******************************************************************************/
162 /******************************************************************************/
163 
164 
165 /******************************************************************************
166 |*
167 |*
168 |*
169 \******************************************************************************/
170 
171 void IMapCircleObject::WriteCERN( SvStream& rOStm, const String& rBaseURL ) const
172 {
173 	ByteString aStr( "circle " );
174 
175 	AppendCERNCoords( aCenter, aStr );
176     aStr += ByteString::CreateFromInt32(nRadius);
177 	aStr += ' ';
178     AppendCERNURL( aStr, rBaseURL );
179 
180 	rOStm.WriteLine( aStr );
181 }
182 
183 
184 /******************************************************************************
185 |*
186 |*
187 |*
188 \******************************************************************************/
189 
190 void IMapCircleObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL ) const
191 {
192 	ByteString aStr( "circle " );
193 
194     AppendNCSAURL( aStr, rBaseURL );
195 	AppendNCSACoords( aCenter, aStr );
196 	AppendNCSACoords( aCenter + Point( nRadius, 0 ), aStr );
197 
198 	rOStm.WriteLine( aStr );
199 }
200 
201 
202 /******************************************************************************/
203 /******************************************************************************/
204 
205 
206 /******************************************************************************
207 |*
208 |*
209 |*
210 \******************************************************************************/
211 
212 void IMapPolygonObject::WriteCERN( SvStream& rOStm, const String& rBaseURL  ) const
213 {
214 	ByteString		aStr( "polygon " );
215 	const sal_uInt16	nCount = aPoly.GetSize();
216 
217 	for ( sal_uInt16 i = 0; i < nCount; i++ )
218 		AppendCERNCoords( aPoly[ i ], aStr );
219 
220     AppendCERNURL( aStr, rBaseURL );
221 
222 	rOStm.WriteLine( aStr );
223 }
224 
225 
226 /******************************************************************************
227 |*
228 |*
229 |*
230 \******************************************************************************/
231 
232 void IMapPolygonObject::WriteNCSA( SvStream& rOStm, const String& rBaseURL  ) const
233 {
234 	ByteString		aStr( "poly " );
235 	const sal_uInt16	nCount = Min( aPoly.GetSize(), (sal_uInt16) 100 );
236 
237     AppendNCSAURL( aStr, rBaseURL );
238 
239 	for ( sal_uInt16 i = 0; i < nCount; i++ )
240 		AppendNCSACoords( aPoly[ i ], aStr );
241 
242 	rOStm.WriteLine( aStr );
243 }
244 
245 
246 /******************************************************************************/
247 /******************************************************************************/
248 
249 
250 /******************************************************************************
251 |*
252 |*
253 |*
254 \******************************************************************************/
255 
256 void ImageMap::Write( SvStream& rOStm, sal_uLong nFormat, const String& rBaseURL ) const
257 {
258 	switch( nFormat )
259 	{
260         case( IMAP_FORMAT_BIN ) : Write( rOStm, rBaseURL );
261         case( IMAP_FORMAT_CERN ) : ImpWriteCERN( rOStm, rBaseURL ); break;
262         case( IMAP_FORMAT_NCSA ) : ImpWriteNCSA( rOStm, rBaseURL ); break;
263 
264 		default:
265 		break;
266 	}
267 }
268 
269 
270 /******************************************************************************
271 |*
272 |*
273 |*
274 \******************************************************************************/
275 
276 void ImageMap::ImpWriteCERN( SvStream& rOStm, const String& rBaseURL ) const
277 {
278 	IMapObject* pObj;
279 	sal_uInt16		nCount = (sal_uInt16) maList.Count();
280 
281 	for ( sal_uInt16 i = 0; i < nCount; i++ )
282 	{
283 		pObj = GetIMapObject( i );
284 
285 		switch( pObj->GetType() )
286 		{
287 			case( IMAP_OBJ_RECTANGLE ):
288                 ( (IMapRectangleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
289 			break;
290 
291 			case( IMAP_OBJ_CIRCLE ):
292                 ( (IMapCircleObject*) pObj )->WriteCERN( rOStm, rBaseURL );
293 			break;
294 
295 			case( IMAP_OBJ_POLYGON ):
296                 ( (IMapPolygonObject*) pObj )->WriteCERN( rOStm, rBaseURL );
297 			break;
298 
299 			default:
300 			break;
301 		}
302 	}
303 }
304 
305 
306 /******************************************************************************
307 |*
308 |*
309 |*
310 \******************************************************************************/
311 
312 void ImageMap::ImpWriteNCSA( SvStream& rOStm, const String& rBaseURL  ) const
313 {
314 	IMapObject* pObj;
315 	sal_uInt16		nCount = (sal_uInt16) maList.Count();
316 
317 	for ( sal_uInt16 i = 0; i < nCount; i++ )
318 	{
319 		pObj = GetIMapObject( i );
320 
321 			switch( pObj->GetType() )
322 		{
323 			case( IMAP_OBJ_RECTANGLE ):
324                 ( (IMapRectangleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
325 			break;
326 
327 			case( IMAP_OBJ_CIRCLE ):
328                 ( (IMapCircleObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
329 			break;
330 
331 			case( IMAP_OBJ_POLYGON ):
332                 ( (IMapPolygonObject*) pObj )->WriteNCSA( rOStm, rBaseURL );
333 			break;
334 
335 			default:
336 			break;
337 		}
338 	}
339 }
340 
341 
342 /******************************************************************************
343 |*
344 |*
345 |*
346 \******************************************************************************/
347 
348 sal_uLong ImageMap::Read( SvStream& rIStm, sal_uLong nFormat, const String& rBaseURL  )
349 {
350 	sal_uLong nRet = IMAP_ERR_FORMAT;
351 
352 	if ( nFormat == IMAP_FORMAT_DETECT )
353 		nFormat = ImpDetectFormat( rIStm );
354 
355 	switch ( nFormat )
356 	{
357         case ( IMAP_FORMAT_BIN )    : Read( rIStm, rBaseURL ); break;
358         case ( IMAP_FORMAT_CERN )   : nRet = ImpReadCERN( rIStm, rBaseURL ); break;
359         case ( IMAP_FORMAT_NCSA )   : nRet = ImpReadNCSA( rIStm, rBaseURL ); break;
360 
361 		default:
362 		break;
363 	}
364 
365 	if ( !rIStm.GetError() )
366 		nRet = IMAP_ERR_OK;
367 
368 	return nRet;
369 }
370 
371 
372 /******************************************************************************
373 |*
374 |*
375 |*
376 \******************************************************************************/
377 
378 sal_uLong ImageMap::ImpReadCERN( SvStream& rIStm, const String& rBaseURL )
379 {
380 	ByteString aStr;
381 
382 	// alten Inhalt loeschen
383 	ClearImageMap();
384 
385 	while ( rIStm.ReadLine( aStr ) )
386         ImpReadCERNLine( aStr, rBaseURL );
387 
388 	return IMAP_ERR_OK;
389 }
390 
391 
392 /******************************************************************************
393 |*
394 |*
395 |*
396 \******************************************************************************/
397 
398 void ImageMap::ImpReadCERNLine( const ByteString& rLine, const String& rBaseURL  )
399 {
400 	ByteString	aStr( rLine );
401 	ByteString	aToken;
402 
403 	aStr.EraseLeadingChars( ' ' );
404 	aStr.EraseLeadingChars( '\t' );
405 	aStr.EraseAllChars( ';' );
406 	aStr.ToLowerAscii();
407 
408 	const char*	pStr = aStr.GetBuffer();
409 	char		cChar = *pStr++;
410 
411 		// Anweisung finden
412 	while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
413 	{
414 		aToken += cChar;
415 		cChar = *pStr++;
416 	}
417 
418 	if ( NOTEOL( cChar ) )
419 	{
420 		if ( ( aToken == "rectangle" ) || ( aToken == "rect" ) )
421 		{
422 			const Point		aTopLeft( ImpReadCERNCoords( &pStr ) );
423 			const Point		aBottomRight( ImpReadCERNCoords( &pStr ) );
424             const String    aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
425 			const Rectangle	aRect( aTopLeft, aBottomRight );
426 
427 			IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
428 			maList.Insert( pObj, LIST_APPEND );
429 		}
430 		else if ( ( aToken == "circle" ) || ( aToken == "circ" ) )
431 		{
432 			const Point		aCenter( ImpReadCERNCoords( &pStr ) );
433 			const long		nRadius = ImpReadCERNRadius( &pStr );
434             const String    aURL( ImpReadCERNURL( &pStr, rBaseURL ) );
435 
436 			IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
437 			maList.Insert( pObj, LIST_APPEND );
438 		}
439 		else if ( ( aToken == "polygon" ) || ( aToken == "poly" ) )
440 		{
441 			const sal_uInt16	nCount = aStr.GetTokenCount( '(' ) - 1;
442 			Polygon			aPoly( nCount );
443 			String			aURL;
444 
445 			for ( sal_uInt16 i = 0; i < nCount; i++ )
446 				aPoly[ i ] = ImpReadCERNCoords( &pStr );
447 
448             aURL = ImpReadCERNURL( &pStr, rBaseURL );
449 
450 			IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
451 			maList.Insert( pObj, LIST_APPEND );
452 		}
453 	}
454 }
455 
456 
457 /******************************************************************************
458 |*
459 |*
460 |*
461 \******************************************************************************/
462 
463 Point ImageMap::ImpReadCERNCoords( const char** ppStr )
464 {
465 	String	aStrX;
466 	String	aStrY;
467 	Point	aPt;
468 	char	cChar = *(*ppStr)++;
469 
470 	while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
471 		cChar = *(*ppStr)++;
472 
473 	if ( NOTEOL( cChar ) )
474 	{
475 		while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
476 		{
477 			aStrX += cChar;
478 			cChar = *(*ppStr)++;
479 		}
480 
481 		if ( NOTEOL( cChar ) )
482 		{
483 			while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
484 				cChar = *(*ppStr)++;
485 
486 			while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
487 			{
488 				aStrY += cChar;
489 				cChar = *(*ppStr)++;
490 			}
491 
492 			if ( NOTEOL( cChar ) )
493 				while( NOTEOL( cChar ) && ( cChar != ')' ) )
494 					cChar = *(*ppStr)++;
495 
496 			aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
497 		}
498 	}
499 
500 	return aPt;
501 }
502 
503 
504 /******************************************************************************
505 |*
506 |*
507 |*
508 \******************************************************************************/
509 
510 long ImageMap::ImpReadCERNRadius( const char** ppStr )
511 {
512 	String	aStr;
513 	char	cChar = *(*ppStr)++;
514 
515 	while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
516 		cChar = *(*ppStr)++;
517 
518 	if ( NOTEOL( cChar ) )
519 	{
520 		while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
521 		{
522 			aStr += cChar;
523 			cChar = *(*ppStr)++;
524 		}
525 	}
526 
527 	return aStr.ToInt32();
528 }
529 
530 
531 /******************************************************************************
532 |*
533 |*
534 |*
535 \******************************************************************************/
536 
537 String ImageMap::ImpReadCERNURL( const char** ppStr, const String& rBaseURL )
538 {
539 	String	aStr( String::CreateFromAscii( *ppStr ) );
540 
541 	aStr.EraseLeadingChars( ' ' );
542 	aStr.EraseLeadingChars( '\t' );
543 	aStr.EraseTrailingChars( ' ' );
544 	aStr.EraseTrailingChars( '\t' );
545 
546     return INetURLObject::GetAbsURL( rBaseURL, aStr );
547 }
548 
549 
550 /******************************************************************************
551 |*
552 |*
553 |*
554 \******************************************************************************/
555 
556 sal_uLong ImageMap::ImpReadNCSA( SvStream& rIStm, const String& rBaseURL )
557 {
558 	ByteString aStr;
559 
560 	// alten Inhalt loeschen
561 	ClearImageMap();
562 
563 	while ( rIStm.ReadLine( aStr ) )
564         ImpReadNCSALine( aStr, rBaseURL );
565 
566 	return IMAP_ERR_OK;
567 }
568 
569 
570 /******************************************************************************
571 |*
572 |*
573 |*
574 \******************************************************************************/
575 
576 void ImageMap::ImpReadNCSALine( const ByteString& rLine, const String& rBaseURL )
577 {
578 	ByteString	aStr( rLine );
579 	ByteString	aToken;
580 
581 	aStr.EraseLeadingChars( ' ' );
582 	aStr.EraseLeadingChars( '\t' );
583 	aStr.EraseAllChars( ';' );
584 	aStr.ToLowerAscii();
585 
586 	const char*	pStr = aStr.GetBuffer();
587 	char		cChar = *pStr++;
588 
589 		// Anweisung finden
590 	while( ( cChar >= 'a' ) && ( cChar <= 'z' ) && NOTEOL( cChar ) )
591 	{
592 		aToken += cChar;
593 		cChar = *pStr++;
594 	}
595 
596 	if ( NOTEOL( cChar ) )
597 	{
598 		if ( aToken == "rect" )
599 		{
600             const String    aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
601 			const Point		aTopLeft( ImpReadNCSACoords( &pStr ) );
602 			const Point		aBottomRight( ImpReadNCSACoords( &pStr ) );
603 			const Rectangle	aRect( aTopLeft, aBottomRight );
604 
605 			IMapRectangleObject* pObj = new IMapRectangleObject( aRect, aURL, String(), String(), String(), String() );
606 			maList.Insert( pObj, LIST_APPEND );
607 		}
608 		else if ( aToken == "circle" )
609 		{
610             const String    aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
611 			const Point		aCenter( ImpReadNCSACoords( &pStr ) );
612 			const Point		aDX( aCenter - ImpReadNCSACoords( &pStr ) );
613 			long			nRadius = (long) sqrt( (double) aDX.X() * aDX.X() +
614 												   (double) aDX.Y() * aDX.Y() );
615 
616 			IMapCircleObject* pObj = new IMapCircleObject( aCenter, nRadius, aURL, String(), String(), String(), String() );
617 			maList.Insert( pObj, LIST_APPEND );
618 		}
619 		else if ( aToken == "poly" )
620 		{
621 			const sal_uInt16	nCount = aStr.GetTokenCount( ',' ) - 1;
622             const String    aURL( ImpReadNCSAURL( &pStr, rBaseURL ) );
623 			Polygon			aPoly( nCount );
624 
625 			for ( sal_uInt16 i = 0; i < nCount; i++ )
626 				aPoly[ i ] = ImpReadNCSACoords( &pStr );
627 
628 			IMapPolygonObject* pObj = new IMapPolygonObject( aPoly, aURL, String(), String(), String(), String() );
629 			maList.Insert( pObj, LIST_APPEND );
630 		}
631 	}
632 }
633 
634 
635 /******************************************************************************
636 |*
637 |*
638 |*
639 \******************************************************************************/
640 
641 String ImageMap::ImpReadNCSAURL( const char** ppStr, const String& rBaseURL )
642 {
643 	String	aStr;
644 	char	cChar = *(*ppStr)++;
645 
646 	while( NOTEOL( cChar ) && ( ( cChar == ' ' ) || ( cChar == '\t' ) ) )
647 		cChar = *(*ppStr)++;
648 
649 	if ( NOTEOL( cChar ) )
650 	{
651 		while( NOTEOL( cChar ) && ( cChar != ' ' ) && ( cChar != '\t' ) )
652 		{
653 			aStr += cChar;
654 			cChar = *(*ppStr)++;
655 		}
656 	}
657 
658     return INetURLObject::GetAbsURL( rBaseURL, aStr );
659 }
660 
661 
662 /******************************************************************************
663 |*
664 |*
665 |*
666 \******************************************************************************/
667 
668 Point ImageMap::ImpReadNCSACoords( const char** ppStr )
669 {
670 	String	aStrX;
671 	String	aStrY;
672 	Point	aPt;
673 	char	cChar = *(*ppStr)++;
674 
675 	while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
676 		cChar = *(*ppStr)++;
677 
678 	if ( NOTEOL( cChar ) )
679 	{
680 		while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
681 		{
682 			aStrX += cChar;
683 			cChar = *(*ppStr)++;
684 		}
685 
686 		if ( NOTEOL( cChar ) )
687 		{
688 			while( NOTEOL( cChar ) && ( ( cChar < '0' ) || ( cChar > '9' ) ) )
689 				cChar = *(*ppStr)++;
690 
691 			while( NOTEOL( cChar ) && ( cChar >= '0' ) && ( cChar <= '9' ) )
692 			{
693 				aStrY += cChar;
694 				cChar = *(*ppStr)++;
695 			}
696 
697 			aPt = Point( aStrX.ToInt32(), aStrY.ToInt32() );
698 		}
699 	}
700 
701 	return aPt;
702 }
703 
704 
705 /******************************************************************************
706 |*
707 |*
708 |*
709 \******************************************************************************/
710 
711 sal_uLong ImageMap::ImpDetectFormat( SvStream& rIStm )
712 {
713 	sal_uLong	nPos = rIStm.Tell();
714 	sal_uLong	nRet = IMAP_FORMAT_BIN;
715 	char	cMagic[6];
716 
717 	rIStm.Read( cMagic, sizeof( cMagic ) );
718 
719 	// Falls wir kein internes Format haben,
720 	// untersuchen wir das Format
721 	if ( memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
722 	{
723 		ByteString	aStr;
724 		long		nCount = 128;
725 
726 		rIStm.Seek( nPos );
727 		while ( rIStm.ReadLine( aStr ) && nCount-- )
728 		{
729 			aStr.ToLowerAscii();
730 
731 			if ( ( aStr.Search( "rect" ) != STRING_NOTFOUND ) ||
732 				 ( aStr.Search( "circ" ) != STRING_NOTFOUND ) ||
733 				 ( aStr.Search( "poly" ) != STRING_NOTFOUND ) )
734 			{
735 				if ( ( aStr.Search( '(' ) != STRING_NOTFOUND ) &&
736 					 ( aStr.Search( ')' ) != STRING_NOTFOUND ) )
737 				{
738 					nRet = IMAP_FORMAT_CERN;
739 				}
740 				else
741 					nRet = IMAP_FORMAT_NCSA;
742 
743 				break;
744 			}
745 		}
746 	}
747 
748 	rIStm.Seek( nPos );
749 
750 	return nRet;
751 }
752