xref: /AOO41X/main/store/workben/t_store.cxx (revision 73d9b18ad12b526a229c2c5ca3fb0f85a41c2f42)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_store.hxx"
26 
27 #define _T_STORE_CXX "$Revision: 1.7.8.2 $"
28 #include <sal/types.h>
29 #include <osl/diagnose.h>
30 #include <osl/thread.h>
31 #include <osl/time.h>
32 #include <rtl/ustring.hxx>
33 #include <store/store.hxx>
34 
35 #include <stdio.h>
36 
37 #if (defined(WNT) && defined(PROFILE))
38 extern "C"
39 {
40     void StartCAP (void);
41     void StopCAP  (void);
42     void DumpCAP  (void);
43 }
44 #endif /* PROFILE */
45 
46 using rtl::OUString;
47 
48 /*========================================================================
49  *
50  * Internals.
51  *
52  *======================================================================*/
53 #define _DEMOSTOR_BUFSIZ          512  /* 4096, 1024, 512 */
54 #define _DEMOSTOR_LOOPS           1000 /* 1000, 2000 */
55 
56 #define _DEMOSTOR_REMOVE          0
57 #define _DEMOSTOR_REBUILD         0
58 
59 enum Options
60 {
61     OPTION_HELP    = 0x0001,
62     OPTION_FILE    = 0x0002,
63     OPTION_PAUSE   = 0x0004,
64     OPTION_REBUILD = 0x0008,
65 
66     OPTION_DUMP    = 0x0010,
67     OPTION_ITER    = 0x0020,
68     OPTION_LINK    = 0x0040,
69 
70     OPTION_READ    = 0x0100,
71     OPTION_WRITE   = 0x0200,
72     OPTION_CREAT   = 0x0400,
73     OPTION_TRUNC   = 0x0800
74 };
75 
ascii_toLowerCase(sal_Char ch)76 inline sal_Char ascii_toLowerCase (sal_Char ch)
77 {
78     if ((ch >= 0x41) && (ch <= 0x5A))
79         return (ch + 0x20);
80     else
81         return (ch);
82 }
83 
84 /*========================================================================
85  *
86  * Timing.
87  *
88  *======================================================================*/
89 struct OTime : public TimeValue
90 {
OTimeOTime91     OTime (void)
92     {
93         Seconds = 0;
94         Nanosec = 0;
95     }
96 
getSystemTimeOTime97     static OTime getSystemTime (void)
98     {
99         OTime tv;
100         osl_getSystemTime (&tv);
101         return tv;
102     }
103 
operator -=OTime104     OTime& operator-= (const OTime& rPast)
105     {
106         Seconds -= rPast.Seconds;
107         if (Nanosec < rPast.Nanosec)
108         {
109             Seconds -= 1;
110             Nanosec += 1000000000;
111         }
112         Nanosec -= rPast.Nanosec;
113         return *this;
114     }
115 
operator -(const OTime & rTimeA,const OTime & rTimeB)116     friend OTime operator- (const OTime& rTimeA, const OTime& rTimeB)
117     {
118         OTime aTimeC (rTimeA);
119         aTimeC -= rTimeB;
120         return aTimeC;
121     }
122 };
123 
124 /*========================================================================
125  *
126  * DirectoryTraveller.
127  *
128  *======================================================================*/
129 typedef store::OStoreDirectory Directory;
130 
131 class DirectoryTraveller : public Directory::traveller
132 {
133     typedef store::OStoreFile   file;
134     typedef Directory::iterator iter;
135 
136     store::OStoreFile m_aFile;
137     OUString          m_aPath;
138 
139     sal_uInt32  m_nOptions;
140     unsigned int  m_nLevel;
141     unsigned int  m_nCount;
142 
143 public:
144     DirectoryTraveller (
145         const file&     rFile,
146         const OUString &rPath,
147         const OUString &rName,
148         sal_uInt32      nOptions,
149         unsigned int nLevel = 0);
150 
151     virtual ~DirectoryTraveller (void);
152 
153     virtual sal_Bool visit (const iter& it);
154 };
155 
156 /*
157  * DirectoryTraveller.
158  */
DirectoryTraveller(const file & rFile,const OUString & rPath,const OUString & rName,sal_uInt32 nOptions,unsigned int nLevel)159 DirectoryTraveller::DirectoryTraveller (
160     const file&     rFile,
161     const OUString &rPath,
162     const OUString &rName,
163     sal_uInt32      nOptions,
164     unsigned int nLevel)
165     : m_aFile    (rFile),
166       m_aPath    (rPath),
167       m_nOptions (nOptions),
168       m_nLevel   (nLevel),
169       m_nCount   (0)
170 {
171     m_aPath += rName;
172     m_aPath += OUString::createFromAscii("/");
173 }
174 
175 /*
176  * ~DirectoryTraveller.
177  */
~DirectoryTraveller(void)178 DirectoryTraveller::~DirectoryTraveller (void)
179 {
180 }
181 
182 /*
183  * visit.
184  */
visit(const iter & it)185 sal_Bool DirectoryTraveller::visit (const iter& it)
186 {
187     m_nCount++;
188     if (m_nOptions & OPTION_DUMP)
189     {
190         rtl::OString aName (it.m_pszName, it.m_nLength, RTL_TEXTENCODING_UTF8);
191         printf ("Visit(%d,%d): %s [0x%08x] %d [Bytes]\n",
192                 m_nLevel, m_nCount,
193                 aName.pData->buffer, (unsigned int)(it.m_nAttrib), (unsigned int)(it.m_nSize));
194     }
195     if (it.m_nAttrib & STORE_ATTRIB_ISDIR)
196     {
197         OUString  aName (it.m_pszName, it.m_nLength);
198         if (aName.compareToAscii ("XTextViewCursorSupplier") == 0)
199         {
200             m_nCount += 1 - 1;
201         }
202         Directory aSubDir;
203 
204         storeError eErrCode = aSubDir.create (
205             m_aFile, m_aPath, aName, store_AccessReadOnly);
206         if (eErrCode == store_E_None)
207         {
208             sal_uInt32 nRefCount = 0;
209             m_aFile.getRefererCount (nRefCount);
210 
211             DirectoryTraveller aSubTraveller (
212                 m_aFile, m_aPath, aName, m_nOptions, m_nLevel + 1);
213             aSubDir.travel (aSubTraveller);
214         }
215     }
216     return sal_True;
217 }
218 
219 /*========================================================================
220  *
221  * main.
222  *
223  *======================================================================*/
main(int argc,char ** argv)224 int SAL_CALL main (int argc, char **argv)
225 {
226 #if (defined(WNT) && defined(PROFILE))
227     StartCAP();
228 #else
229     OTime aMainStartTime (OTime::getSystemTime());
230 #endif /* PROFILE */
231 
232     store::OStoreFile aFile;
233     storeError eErrCode = store_E_None;
234 
235     sal_uInt32 nOptions = 0;
236     for (int i = 1; i < argc; i++)
237     {
238         const char *opt = argv[i];
239         if (opt[0] == '-')
240         {
241             switch (ascii_toLowerCase(sal_Char(opt[1])))
242             {
243                 case 'f':
244                     nOptions |= OPTION_FILE;
245                     break;
246 
247                 case 'd':
248                     nOptions |= OPTION_DUMP;
249                     break;
250                 case 'i':
251                     nOptions |= OPTION_ITER;
252                     break;
253                 case 'l':
254                     nOptions |= OPTION_LINK;
255                     break;
256 
257                 case 'r':
258                     nOptions |= OPTION_READ;
259                     break;
260                 case 'w':
261                     nOptions |= OPTION_WRITE;
262                     break;
263                 case 'c':
264                     nOptions |= OPTION_CREAT;
265                     break;
266                 case 't':
267                     nOptions |= OPTION_TRUNC;
268                     break;
269 
270                 case 'p':
271                     nOptions |= OPTION_PAUSE;
272                     break;
273 
274                 case 'h':
275                 default:
276                     nOptions |= OPTION_HELP;
277                     break;
278             }
279         }
280         else
281         {
282             if (nOptions & OPTION_FILE)
283             {
284                 OUString aName (
285                     argv[i], rtl_str_getLength(argv[i]),
286                     osl_getThreadTextEncoding());
287                 if ((nOptions & OPTION_CREAT) && (nOptions & OPTION_TRUNC))
288                     eErrCode = aFile.create (aName, store_AccessCreate);
289                 else if (nOptions & OPTION_CREAT)
290                     eErrCode = aFile.create (aName, store_AccessReadCreate);
291                 else if (nOptions & OPTION_WRITE)
292                     eErrCode = aFile.create (aName, store_AccessReadWrite);
293                 else
294                     eErrCode = aFile.create (aName, store_AccessReadOnly);
295                 if (eErrCode != store_E_None)
296                 {
297                     printf ("Error: can't open file: %s\n", argv[i]);
298                     exit (0);
299                 }
300             }
301         }
302     }
303 
304     if ((nOptions == 0) || (nOptions & OPTION_HELP))
305     {
306         printf ("Usage:\tt_store "
307                 "[[-c] [-t] [-r] [-w]] [[-i] [-d] [-h]] "
308                 "[-f filename]\n");
309 
310         printf ("\nOptions:\n");
311         printf ("-c\tcreate\n");
312         printf ("-t\ttruncate\n");
313         printf ("-r\tread\n");
314         printf ("-w\twrite\n");
315         printf ("-i\titerate\n");
316         printf ("-d\tdump\n");
317         printf ("-h\thelp\n");
318         printf ("-f\tfilename\n");
319 
320         printf ("\nExamples:");
321         printf ("\nt_store -c -w -f t_store.rdb\n");
322         printf ("\tCreate file 't_store.rdb',\n"
323                 "\twrite fixed number (1000) of streams.\n");
324         printf ("\nt_store -c -i -d -f t_store.rdb\n");
325         printf ("\tOpen file 't_store.rdb', "
326                 "create '/' directory,\n"
327                 "\titerate directory tree, "
328                 "dump directory info.\n");
329 
330         exit (0);
331     }
332 
333     if (!aFile.isValid())
334     {
335         eErrCode = aFile.createInMemory();
336         if (eErrCode != store_E_None)
337         {
338             printf ("Error: can't create memory file\n");
339             exit (0);
340         }
341     }
342 
343     // Stream Read/Write.
344     OUString aPath (RTL_CONSTASCII_USTRINGPARAM("/"));
345     if ((nOptions & OPTION_READ) || (nOptions & OPTION_WRITE))
346     {
347         // Mode.
348         storeAccessMode eMode = store_AccessReadOnly;
349         if (nOptions & OPTION_WRITE)
350             eMode = store_AccessReadWrite;
351         if (nOptions & OPTION_CREAT)
352             eMode = store_AccessCreate;
353 
354         // Buffer.
355         char pBuffer[_DEMOSTOR_BUFSIZ] = "Hello World";
356         pBuffer[_DEMOSTOR_BUFSIZ - 2] = 'B';
357         pBuffer[_DEMOSTOR_BUFSIZ - 1] = '\0';
358 
359         // Load/Save.
360 #ifndef PROFILE
361         OTime aStartTime (OTime::getSystemTime());
362 #endif /* PROFILE */
363 
364         for (int i = 0; i < _DEMOSTOR_LOOPS; i++)
365         {
366             OUString aName (RTL_CONSTASCII_USTRINGPARAM("demostor-"));
367             aName += OUString::valueOf ((sal_Int32)(i + 1), 10);
368             aName += OUString::createFromAscii (".dat");
369 
370 #if (_DEMOSTOR_REMOVE == 1)
371             eErrCode = aFile.remove (aPath, aName);
372             if ((eErrCode != store_E_None     ) &&
373                 (eErrCode != store_E_NotExists)    )
374                 break;
375 #endif /* _REMOVE */
376 
377             store::OStoreStream aStream;
378             eErrCode = aStream.create (aFile, aPath, aName, eMode);
379             if (eErrCode != store_E_None)
380             {
381                 OSL_TRACE("OStoreStream(%d)::create(): error: %d", i, eErrCode);
382                 break;
383             }
384 
385             if (nOptions & OPTION_TRUNC)
386             {
387                 eErrCode = aStream.setSize(0);
388                 if (eErrCode != store_E_None)
389                 {
390                     OSL_TRACE("OStoreStream(%d)::setSize(0): error: %d", i, eErrCode);
391                     break;
392                 }
393             }
394 
395             sal_uInt32 nDone = 0;
396             if (nOptions & OPTION_WRITE)
397             {
398                 eErrCode = aStream.writeAt (
399                     0, pBuffer, sizeof(pBuffer), nDone);
400                 if (eErrCode != store_E_None)
401                 {
402                     OSL_TRACE("OStoreStream(%d)::writeAt(): error: %d", i, eErrCode);
403                     break;
404                 }
405             }
406 
407             if (nOptions & OPTION_READ)
408             {
409                 sal_uInt32 nOffset = 0;
410                 for (;;)
411                 {
412                     eErrCode = aStream.readAt (
413                         nOffset, pBuffer, sizeof(pBuffer), nDone);
414                     if (eErrCode != store_E_None)
415                     {
416                         OSL_TRACE("OStoreStream(%d)::readAt(): error: %d", i, eErrCode);
417                         break;
418                     }
419                     if (nDone == 0)
420                         break;
421                     nOffset += nDone;
422                 }
423             }
424 
425             aStream.close();
426 
427 #ifndef PROFILE
428             if (((i + 1) % (_DEMOSTOR_LOOPS/10)) == 0)
429             {
430                 OTime aDelta (OTime::getSystemTime() - aStartTime);
431 
432                 sal_uInt32 nDelta = aDelta.Seconds * 1000000;
433                 nDelta += (aDelta.Nanosec / 1000);
434 
435                 printf ("%d: %12.4g[usec]\n", (i+1),
436                         (double)(nDelta)/(double)(i+1));
437             }
438 #endif /* PROFILE */
439         }
440 
441 #ifndef PROFILE
442         OTime aDelta (OTime::getSystemTime() - aStartTime);
443 
444         sal_uInt32 nDelta = aDelta.Seconds * 1000000;
445         nDelta += (aDelta.Nanosec / 1000);
446 
447         printf ("Total(rd,wr): %d[usec]\n", (unsigned int)(nDelta));
448 #endif /* PROFILE */
449     }
450 
451     // Link/Rename.
452     if (nOptions & OPTION_LINK)
453     {
454         // Create symlink to (root) directory.
455         eErrCode = aFile.symlink (
456             aPath,      OUString::createFromAscii("000000/"),
457             OUString(), aPath);
458         OSL_POSTCOND(
459             ((eErrCode == store_E_None         ) ||
460              (eErrCode == store_E_AlreadyExists)    ),
461             "t_store::main(): store_symlink() failed");
462 
463         // Create symlink to file.
464         OUString aLinkName (RTL_CONSTASCII_USTRINGPARAM("demostor-1.lnk"));
465 
466         eErrCode = aFile.symlink (
467             aPath, aLinkName,
468             aPath, OUString::createFromAscii("demostor-1.dat"));
469         OSL_POSTCOND(
470             ((eErrCode == store_E_None         ) ||
471              (eErrCode == store_E_AlreadyExists)    ),
472             "t_store::main(): store_symlink() failed");
473         if ((eErrCode == store_E_None         ) ||
474             (eErrCode == store_E_AlreadyExists)    )
475         {
476             OUString aShortcut (
477                 RTL_CONSTASCII_USTRINGPARAM("Shortcut to demostor-1.dat"));
478             eErrCode = aFile.rename (
479                 aPath, aLinkName,
480                 aPath, aShortcut);
481             OSL_POSTCOND(
482                 ((eErrCode == store_E_None         ) ||
483                  (eErrCode == store_E_AlreadyExists)    ),
484                 "t_store::main(): store_rename() failed");
485         }
486 
487         // Create directory.
488         OUString aDirName (RTL_CONSTASCII_USTRINGPARAM("demostor-1.dir"));
489         store::OStoreDirectory aDir;
490 
491         eErrCode = aDir.create (
492             aFile, aPath, aDirName, store_AccessReadCreate);
493         OSL_POSTCOND(
494             (eErrCode == store_E_None),
495             "t_store::main(): store_createDirectory() failed");
496         if (eErrCode == store_E_None)
497         {
498 #if 0  /* NYI */
499             // Rename directory.
500             eErrCode = aFile.rename (
501                 aPath, "demostor-1.dir/",
502                 aPath, "Renamed demostor-1.dir");
503             OSL_POSTCOND(
504                 ((eErrCode == store_E_None         ) ||
505                  (eErrCode == store_E_AlreadyExists)    ),
506                 "t_store::main(): store_rename() failed");
507 
508             eErrCode = aFile.rename (
509                 aPath, "Renamed demostor-1.dir/",
510                 aPath, "demostor-1.dir");
511             OSL_POSTCOND(
512                 (eErrCode == store_E_None),
513                 "t_store::main(): store_rename() failed");
514 #endif  /* NYI */
515         }
516     }
517 
518     // Directory iteration.
519     if (nOptions & OPTION_ITER)
520     {
521 #ifndef PROFILE
522         OTime aStartTime (OTime::getSystemTime());
523 #endif /* PROFILE */
524         OUString aEmpty;
525 
526         // Root directory.
527         store::OStoreDirectory aRootDir;
528         if (nOptions & OPTION_LINK)
529         {
530             // Open symlink entry.
531             eErrCode = aRootDir.create (
532                 aFile, aPath, OUString::createFromAscii("000000"),
533                 store_AccessReadOnly);
534         }
535         else
536         {
537             // Open direct entry.
538             if (nOptions & OPTION_CREAT)
539                 eErrCode = aRootDir.create (
540                     aFile, aEmpty, aEmpty, store_AccessReadCreate);
541             else if (nOptions & OPTION_WRITE)
542                 eErrCode = aRootDir.create (
543                     aFile, aEmpty, aEmpty, store_AccessReadWrite);
544             else
545                 eErrCode = aRootDir.create (
546                     aFile, aEmpty, aEmpty, store_AccessReadOnly);
547         }
548 
549         if (eErrCode == store_E_None)
550         {
551             // Traverse directory tree.
552             DirectoryTraveller aTraveller (
553                 aFile, aEmpty, aEmpty, nOptions, 0);
554             aRootDir.travel (aTraveller);
555         }
556         else
557         {
558             // Failure.
559             printf ("Error: can't open directory: \"/\"\n");
560         }
561 
562 #ifndef PROFILE
563         OTime aDelta (OTime::getSystemTime() - aStartTime);
564 
565         sal_uInt32 nDelta = aDelta.Seconds * 1000000;
566         nDelta += (aDelta.Nanosec / 1000);
567 
568         printf ("Total(iter): %d[usec]\n", (unsigned int)(nDelta));
569 #endif /* PROFILE */
570     }
571 
572     if (nOptions & OPTION_PAUSE)
573     {
574         TimeValue tv;
575         tv.Seconds = 300;
576         tv.Nanosec = 0;
577         osl_waitThread (&tv);
578     }
579 
580     // Size.
581     sal_uInt32 nSize = 0;
582     aFile.getSize (nSize);
583 
584     // Done.
585     aFile.close();
586 
587 #if (defined(WNT) && defined(PROFILE))
588     StopCAP();
589     DumpCAP();
590 #endif /* PROFILE */
591 #ifndef PROFILE
592     OTime aDelta (OTime::getSystemTime() - aMainStartTime);
593 
594     sal_uInt32 nDelta = aDelta.Seconds * 1000000;
595     nDelta += (aDelta.Nanosec / 1000);
596 
597     printf ("Total: %d[usec]\n", (unsigned int)(nDelta));
598 #endif /* PROFILE */
599 
600     return 0;
601 }
602