~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/db/mork/src/orkinFactory.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-  */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1999
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#ifndef _MDB_
 
40
#include "mdb.h"
 
41
#endif
 
42
 
 
43
#ifndef _MORK_
 
44
#include "mork.h"
 
45
#endif
 
46
 
 
47
#ifndef _MORKNODE_
 
48
#include "morkNode.h"
 
49
#endif
 
50
 
 
51
#ifndef _MORKHANDLE_
 
52
#include "morkHandle.h"
 
53
#endif
 
54
 
 
55
#ifndef _MORKENV_
 
56
#include "morkEnv.h"
 
57
#endif
 
58
 
 
59
#ifndef _MORKFACTORY_
 
60
#include "morkFactory.h"
 
61
#endif
 
62
 
 
63
#ifndef _ORKINFACTORY_
 
64
#include "orkinFactory.h"
 
65
#endif
 
66
 
 
67
#ifndef _ORKINENV_
 
68
#include "orkinEnv.h"
 
69
#endif
 
70
 
 
71
#ifndef _MORKROW_
 
72
#include "morkRow.h"
 
73
#endif
 
74
 
 
75
#ifndef _ORKINROW_
 
76
#include "orkinRow.h"
 
77
#endif
 
78
 
 
79
#ifndef _MORKFILE_
 
80
#include "morkFile.h"
 
81
#endif
 
82
 
 
83
#ifndef _MORKWRITER_
 
84
#include "morkWriter.h"
 
85
#endif
 
86
 
 
87
#ifndef _MORKSTORE_
 
88
#include "morkStore.h"
 
89
#endif
 
90
 
 
91
#ifndef _ORKINSTORE_
 
92
#include "orkinStore.h"
 
93
#endif
 
94
 
 
95
#ifndef _ORKINTHUMB_
 
96
#include "orkinThumb.h"
 
97
#endif
 
98
 
 
99
#ifndef _MORKTHUMB_
 
100
#include "morkThumb.h"
 
101
#endif
 
102
 
 
103
#ifndef _ORKINHEAP_
 
104
#include "orkinHeap.h"
 
105
#endif
 
106
 
 
107
#ifndef _ORKINCOMPARE_
 
108
#include "orkinCompare.h"
 
109
#endif
 
110
 
 
111
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
 
112
 
 
113
/* public virtual*/
 
114
orkinFactory:: ~orkinFactory() // morkHandle destructor does everything
 
115
{
 
116
}
 
117
 
 
118
/*protected non-poly construction*/
 
119
orkinFactory::orkinFactory(morkEnv* ev, // morkUsage is morkUsage_kPool
 
120
    morkHandleFace* ioFace,    // must not be nil, cookie for this handle
 
121
    morkFactory* ioObject)  // must not be nil, object for this handle
 
122
: morkHandle(ev, ioFace, ioObject, morkMagic_kFactory)
 
123
{
 
124
  // do not modify mNode_Derived; leave it equal to morkDerived_kHandle
 
125
}
 
126
 
 
127
extern "C" nsIMdbFactory* MakeMdbFactory() 
 
128
{
 
129
  return orkinFactory::MakeGlobalFactory();
 
130
}
 
131
 
 
132
/*static */ orkinFactory*
 
133
orkinFactory::MakeGlobalFactory()
 
134
// instantiate objects using almost no context information.
 
135
{
 
136
  morkFactory* factory = new morkFactory(new orkinHeap());
 
137
  MORK_ASSERT(factory);
 
138
  if ( factory )
 
139
    return orkinFactory::MakeFactory(&factory->mFactory_Env, factory);
 
140
  else
 
141
    return (orkinFactory*) 0;
 
142
}
 
143
 
 
144
/*static */ orkinFactory*
 
145
orkinFactory::MakeFactory(morkEnv* ev,  morkFactory* ioObject)
 
146
{
 
147
  mork_bool isEnv = ev->IsEnv();
 
148
  MORK_ASSERT(isEnv);
 
149
  if ( isEnv )
 
150
  {
 
151
    morkHandleFace* face = ev->NewHandle(sizeof(orkinFactory));
 
152
    if ( face )
 
153
    {
 
154
      orkinFactory* f = new(face) orkinFactory(ev, face, ioObject);
 
155
      if ( f )
 
156
        f->mNode_Refs += morkFactory_kWeakRefCountBonus;
 
157
      return f;
 
158
    }
 
159
    else
 
160
      ev->OutOfMemoryError();
 
161
  }
 
162
    
 
163
  return (orkinFactory*) 0;
 
164
}
 
165
 
 
166
morkEnv*
 
167
orkinFactory::CanUseFactory(nsIMdbEnv* mev, mork_bool inMutable,
 
168
  mdb_err* outErr) const
 
169
{
 
170
  morkEnv* outEnv = 0;
 
171
  morkEnv* ev = morkEnv::FromMdbEnv(mev);
 
172
  if ( ev )
 
173
  {
 
174
    morkFactory* factory = (morkFactory*)
 
175
      this->GetGoodHandleObject(ev, inMutable, morkMagic_kFactory,
 
176
        /*inClosedOkay*/ morkBool_kFalse);
 
177
    if ( factory )
 
178
    {
 
179
      if ( factory->IsFactory() )
 
180
        outEnv = ev;
 
181
      else
 
182
        factory->NonFactoryTypeError(ev);
 
183
    }
 
184
    *outErr = ev->AsErr();
 
185
  }
 
186
  MORK_ASSERT(outEnv);
 
187
  return outEnv;
 
188
}
 
189
 
 
190
morkEnv* orkinFactory::GetInternalFactoryEnv(mdb_err* outErr)
 
191
{
 
192
  morkEnv* outEnv = 0;
 
193
  morkFactory* f = (morkFactory*) this->mHandle_Object;
 
194
  if ( f && f->IsNode() && f->IsOpenNode() && f->IsFactory() )
 
195
  {
 
196
    morkEnv* fenv = &f->mFactory_Env;
 
197
    if ( fenv && fenv->IsNode() && fenv->IsOpenNode() && fenv->IsEnv() )
 
198
    {
 
199
      fenv->ClearMorkErrorsAndWarnings(); // drop any earlier errors
 
200
      outEnv = fenv;
 
201
    }
 
202
    else
 
203
      *outErr = morkEnv_kBadFactoryEnvError;
 
204
  }
 
205
  else
 
206
    *outErr = morkEnv_kBadFactoryError;
 
207
    
 
208
  return outEnv;
 
209
}
 
210
 
 
211
// { ===== begin nsIMdbISupports methods =====
 
212
NS_IMPL_QUERY_INTERFACE0(orkinFactory)
 
213
 
 
214
/*virtual*/ nsrefcnt
 
215
orkinFactory::AddRef() // add strong ref with no
 
216
{
 
217
  morkEnv* ev = mHandle_Env;
 
218
  if ( ev && ev->IsEnv() )
 
219
    return this->Handle_AddStrongRef(ev->AsMdbEnv());
 
220
  else
 
221
    return morkEnv_kNonEnvTypeError;
 
222
}
 
223
 
 
224
/*virtual*/ nsrefcnt
 
225
orkinFactory::Release() // cut strong ref
 
226
{
 
227
  morkEnv* ev = mHandle_Env;
 
228
  if ( ev && ev->IsEnv() )
 
229
    return this->Handle_CutStrongRef(ev->AsMdbEnv());
 
230
  else
 
231
    return morkEnv_kNonEnvTypeError;
 
232
}
 
233
// } ===== end nsIMdbObject methods =====
 
234
 
 
235
 
 
236
// { ===== begin nsIMdbObject methods =====
 
237
 
 
238
// { ----- begin attribute methods -----
 
239
/*virtual*/ mdb_err
 
240
orkinFactory::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
 
241
{
 
242
  return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
 
243
}
 
244
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
 
245
// } ----- end attribute methods -----
 
246
 
 
247
// { ----- begin factory methods -----
 
248
/*virtual*/ mdb_err
 
249
orkinFactory::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
 
250
{
 
251
  return this->Handle_GetMdbFactory(mev, acqFactory);
 
252
 
253
// } ----- end factory methods -----
 
254
 
 
255
// { ----- begin ref counting for well-behaved cyclic graphs -----
 
256
/*virtual*/ mdb_err
 
257
orkinFactory::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
 
258
  mdb_count* outCount)
 
259
{
 
260
  return this->Handle_GetWeakRefCount(mev, outCount);
 
261
}  
 
262
/*virtual*/ mdb_err
 
263
orkinFactory::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
 
264
  mdb_count* outCount)
 
265
{
 
266
  return this->Handle_GetStrongRefCount(mev, outCount);
 
267
}
 
268
 
 
269
/*virtual*/ mdb_err
 
270
orkinFactory::AddWeakRef(nsIMdbEnv* mev)
 
271
{
 
272
  return this->Handle_AddWeakRef(mev);
 
273
}
 
274
/*virtual*/ mdb_err
 
275
orkinFactory::AddStrongRef(nsIMdbEnv* mev)
 
276
{
 
277
  return this->Handle_AddStrongRef(mev);
 
278
}
 
279
 
 
280
/*virtual*/ mdb_err
 
281
orkinFactory::CutWeakRef(nsIMdbEnv* mev)
 
282
{
 
283
  return this->Handle_CutWeakRef(mev);
 
284
}
 
285
/*virtual*/ mdb_err
 
286
orkinFactory::CutStrongRef(nsIMdbEnv* mev)
 
287
{
 
288
  return this->Handle_CutStrongRef(mev);
 
289
}
 
290
 
 
291
/*virtual*/ mdb_err
 
292
orkinFactory::CloseMdbObject(nsIMdbEnv* mev)
 
293
{
 
294
  return this->Handle_CloseMdbObject(mev);
 
295
}
 
296
 
 
297
/*virtual*/ mdb_err
 
298
orkinFactory::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
 
299
{
 
300
  return this->Handle_IsOpenMdbObject(mev, outOpen);
 
301
}
 
302
// } ----- end ref counting -----
 
303
 
 
304
// } ===== end nsIMdbObject methods =====
 
305
 
 
306
// { ===== begin nsIMdbFactory methods =====
 
307
 
 
308
// { ----- begin file methods -----
 
309
/*virtual*/ mdb_err
 
310
orkinFactory::OpenOldFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
 
311
  const char* inFilePath,
 
312
  mork_bool inFrozen, nsIMdbFile** acqFile)
 
313
  // Choose some subclass of nsIMdbFile to instantiate, in order to read
 
314
  // (and write if not frozen) the file known by inFilePath.  The file
 
315
  // returned should be open and ready for use, and presumably positioned
 
316
  // at the first byte position of the file.  The exact manner in which
 
317
  // files must be opened is considered a subclass specific detail, and
 
318
  // other portions or Mork source code don't want to know how it's done.
 
319
{
 
320
  mdb_err outErr = 0;
 
321
  nsIMdbFile* outFile = 0;
 
322
  morkEnv* ev = this->CanUseFactory(mev,
 
323
    /*inMutable*/ morkBool_kFalse, &outErr);
 
324
  morkFile* file = nsnull;
 
325
  if ( ev )
 
326
  {
 
327
    morkFactory* factory = (morkFactory*) this->mHandle_Object;
 
328
    if ( !ioHeap )
 
329
      ioHeap = &factory->mFactory_Heap;
 
330
      
 
331
    file = morkFile::OpenOldFile(ev, ioHeap, inFilePath, inFrozen);
 
332
    NS_IF_ADDREF( file );
 
333
      
 
334
    outErr = ev->AsErr();
 
335
  }
 
336
  if ( acqFile )
 
337
    *acqFile = file;
 
338
    
 
339
  return outErr;
 
340
}
 
341
 
 
342
/*virtual*/ mdb_err
 
343
orkinFactory::CreateNewFile(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
 
344
  const char* inFilePath, nsIMdbFile** acqFile)
 
345
  // Choose some subclass of nsIMdbFile to instantiate, in order to read
 
346
  // (and write if not frozen) the file known by inFilePath.  The file
 
347
  // returned should be created and ready for use, and presumably positioned
 
348
  // at the first byte position of the file.  The exact manner in which
 
349
  // files must be opened is considered a subclass specific detail, and
 
350
  // other portions or Mork source code don't want to know how it's done.
 
351
{
 
352
  mdb_err outErr = 0;
 
353
  nsIMdbFile* outFile = 0;
 
354
  morkEnv* ev = this->CanUseFactory(mev,
 
355
    /*inMutable*/ morkBool_kFalse, &outErr);
 
356
  morkFile* file = nsnull;
 
357
  if ( ev )
 
358
  {
 
359
    morkFactory* factory = (morkFactory*) this->mHandle_Object;
 
360
    if ( !ioHeap )
 
361
      ioHeap = &factory->mFactory_Heap;
 
362
      
 
363
    file = morkFile::CreateNewFile(ev, ioHeap, inFilePath);
 
364
    if ( file )
 
365
      NS_ADDREF(file);
 
366
      
 
367
    outErr = ev->AsErr();
 
368
  }
 
369
  if ( acqFile )
 
370
    *acqFile = file;
 
371
    
 
372
  return outErr;
 
373
}
 
374
// } ----- end file methods -----
 
375
 
 
376
// { ----- begin env methods -----
 
377
/*virtual*/ mdb_err
 
378
orkinFactory::MakeEnv(nsIMdbHeap* ioHeap, nsIMdbEnv** acqEnv)
 
379
// ioHeap can be nil, causing a MakeHeap() style heap instance to be used
 
380
{
 
381
  mdb_err outErr = 0;
 
382
  nsIMdbEnv* outEnv = 0;
 
383
  mork_bool ownsHeap = (ioHeap == 0);
 
384
  if ( !ioHeap )
 
385
    ioHeap = new orkinHeap();
 
386
 
 
387
  if ( acqEnv && ioHeap )
 
388
  {
 
389
    morkEnv* fenv = this->GetInternalFactoryEnv(&outErr);
 
390
    if ( fenv )
 
391
    {
 
392
      morkFactory* factory = (morkFactory*) this->mHandle_Object;
 
393
      morkEnv* newEnv = new(*ioHeap, fenv)
 
394
        morkEnv(morkUsage::kHeap, ioHeap, factory, ioHeap);
 
395
 
 
396
      if ( newEnv )
 
397
      {
 
398
        newEnv->mEnv_OwnsHeap = ownsHeap;
 
399
        newEnv->mNode_Refs += morkEnv_kWeakRefCountEnvBonus;
 
400
        NS_ADDREF(newEnv);
 
401
        newEnv->mEnv_SelfAsMdbEnv = newEnv;
 
402
        outEnv = newEnv;
 
403
      }
 
404
      else
 
405
        outErr = morkEnv_kOutOfMemoryError;
 
406
    }
 
407
    
 
408
    *acqEnv = outEnv;
 
409
  }
 
410
  else
 
411
    outErr = morkEnv_kNilPointerError;
 
412
    
 
413
  return outErr;
 
414
}
 
415
// } ----- end env methods -----
 
416
 
 
417
// { ----- begin heap methods -----
 
418
/*virtual*/ mdb_err
 
419
orkinFactory::MakeHeap(nsIMdbEnv* mev, nsIMdbHeap** acqHeap)
 
420
{
 
421
  mdb_err outErr = 0;
 
422
  nsIMdbHeap* outHeap = 0;
 
423
  morkEnv* ev = this->CanUseFactory(mev,
 
424
    /*inMutable*/ morkBool_kFalse, &outErr);
 
425
  if ( ev )
 
426
  {
 
427
    outHeap = new orkinHeap();
 
428
    if ( !outHeap )
 
429
      ev->OutOfMemoryError();
 
430
  }
 
431
  MORK_ASSERT(acqHeap);
 
432
  if ( acqHeap )
 
433
    *acqHeap = outHeap;
 
434
  return outErr;
 
435
}
 
436
// } ----- end heap methods -----
 
437
 
 
438
// { ----- begin compare methods -----
 
439
/*virtual*/ mdb_err
 
440
orkinFactory::MakeCompare(nsIMdbEnv* mev, nsIMdbCompare** acqCompare)
 
441
{
 
442
  mdb_err outErr = 0;
 
443
  nsIMdbCompare* outCompare = 0;
 
444
  morkEnv* ev = this->CanUseFactory(mev,
 
445
    /*inMutable*/ morkBool_kFalse, &outErr);
 
446
  if ( ev )
 
447
  {
 
448
    NS_ASSERTION(PR_FALSE, "not implemented");
 
449
    outErr = NS_ERROR_NOT_IMPLEMENTED;
 
450
//    outCompare = new orkinCompare();
 
451
    if ( !outCompare )
 
452
      ev->OutOfMemoryError();
 
453
  }
 
454
  if ( acqCompare )
 
455
    *acqCompare = outCompare;
 
456
  return outErr;
 
457
}
 
458
// } ----- end compare methods -----
 
459
 
 
460
// { ----- begin row methods -----
 
461
/*virtual*/ mdb_err
 
462
orkinFactory::MakeRow(nsIMdbEnv* mev, nsIMdbHeap* ioHeap,
 
463
  nsIMdbRow** acqRow)
 
464
{
 
465
  MORK_USED_1(ioHeap);
 
466
  mdb_err outErr = 0;
 
467
  nsIMdbRow* outRow = 0;
 
468
  morkEnv* ev = this->CanUseFactory(mev,
 
469
    /*inMutable*/ morkBool_kFalse, &outErr);
 
470
  if ( ev )
 
471
  {
 
472
    ev->StubMethodOnlyError();
 
473
    outErr = ev->AsErr();
 
474
  }
 
475
  if ( acqRow )
 
476
    *acqRow = outRow;
 
477
    
 
478
  return outErr;
 
479
}
 
480
// ioHeap can be nil, causing the heap associated with ev to be used
 
481
// } ----- end row methods -----
 
482
 
 
483
// { ----- begin port methods -----
 
484
/*virtual*/ mdb_err
 
485
orkinFactory::CanOpenFilePort(
 
486
  nsIMdbEnv* mev, // context
 
487
  // const char* inFilePath, // the file to investigate
 
488
  // const mdbYarn* inFirst512Bytes,
 
489
  nsIMdbFile* ioFile, // db abstract file interface
 
490
  mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
 
491
  mdbYarn* outFormatVersion)
 
492
{
 
493
  mdb_err outErr = 0;
 
494
  if ( outFormatVersion )
 
495
  {
 
496
    outFormatVersion->mYarn_Fill = 0;
 
497
  }
 
498
  mdb_bool canOpenAsPort = morkBool_kFalse;
 
499
  morkEnv* ev = this->CanUseFactory(mev,
 
500
    /*inMutable*/ morkBool_kFalse, &outErr);
 
501
  if ( ev )
 
502
  {
 
503
    if ( ioFile && outCanOpen )
 
504
    {
 
505
      canOpenAsPort = this->CanOpenMorkTextFile(ev, ioFile);
 
506
    }
 
507
    else
 
508
      ev->NilPointerError();
 
509
    
 
510
    outErr = ev->AsErr();
 
511
  }
 
512
    
 
513
  if ( outCanOpen )
 
514
    *outCanOpen = canOpenAsPort;
 
515
    
 
516
  return outErr;
 
517
}
 
518
  
 
519
/*virtual*/ mdb_err
 
520
orkinFactory::OpenFilePort(
 
521
  nsIMdbEnv* mev, // context
 
522
  nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
 
523
  // const char* inFilePath, // the file to open for readonly import
 
524
  nsIMdbFile* ioFile, // db abstract file interface
 
525
  const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
 
526
  nsIMdbThumb** acqThumb)
 
527
{
 
528
  MORK_USED_1(ioHeap);
 
529
  mdb_err outErr = 0;
 
530
  nsIMdbThumb* outThumb = 0;
 
531
  morkEnv* ev = this->CanUseFactory(mev,
 
532
    /*inMutable*/ morkBool_kFalse, &outErr);
 
533
  if ( ev )
 
534
  {
 
535
    if ( ioFile && inOpenPolicy && acqThumb )
 
536
    {
 
537
    }
 
538
    else
 
539
      ev->NilPointerError();
 
540
    
 
541
    outErr = ev->AsErr();
 
542
  }
 
543
  if ( acqThumb )
 
544
    *acqThumb = outThumb;
 
545
  return outErr;
 
546
}
 
547
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
 
548
// then call nsIMdbFactory::ThumbToOpenPort() to get the port instance.
 
549
 
 
550
/*virtual*/ mdb_err
 
551
orkinFactory::ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort()
 
552
  nsIMdbEnv* mev, // context
 
553
  nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status
 
554
  nsIMdbPort** acqPort)
 
555
{
 
556
  mdb_err outErr = 0;
 
557
  nsIMdbPort* outPort = 0;
 
558
  morkEnv* ev = this->CanUseFactory(mev,
 
559
    /*inMutable*/ morkBool_kFalse, &outErr);
 
560
  if ( ev )
 
561
  {
 
562
    if ( ioThumb && acqPort )
 
563
    {
 
564
      morkThumb* thumb = (morkThumb*) ioThumb;
 
565
      morkStore* store = thumb->ThumbToOpenStore(ev);
 
566
      if ( store )
 
567
      {
 
568
        store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
 
569
        store->mStore_CanDirty = morkBool_kTrue;
 
570
        store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue);
 
571
        
 
572
        NS_ADDREF(store);
 
573
        outPort = store;
 
574
      }
 
575
    }
 
576
    else
 
577
      ev->NilPointerError();
 
578
    
 
579
    outErr = ev->AsErr();
 
580
  }
 
581
  if ( acqPort )
 
582
    *acqPort = outPort;
 
583
  return outErr;
 
584
}
 
585
// } ----- end port methods -----
 
586
 
 
587
mork_bool
 
588
orkinFactory::CanOpenMorkTextFile(morkEnv* ev,
 
589
  // const mdbYarn* inFirst512Bytes,
 
590
  nsIMdbFile* ioFile)
 
591
{
 
592
  MORK_USED_1(ev);
 
593
  mork_bool outBool = morkBool_kFalse;
 
594
  mork_size headSize = MORK_STRLEN(morkWriter_kFileHeader);
 
595
  
 
596
  char localBuf[ 256 + 4 ]; // for extra for sloppy safety
 
597
  mdbYarn localYarn;
 
598
  mdbYarn* y = &localYarn;
 
599
  y->mYarn_Buf = localBuf; // space to hold content
 
600
  y->mYarn_Fill = 0;       // no logical content yet
 
601
  y->mYarn_Size = 256;     // physical capacity is 256 bytes
 
602
  y->mYarn_More = 0;
 
603
  y->mYarn_Form = 0;
 
604
  y->mYarn_Grow = 0;
 
605
  
 
606
  if ( ioFile )
 
607
  {
 
608
    nsIMdbEnv* menv = ev->AsMdbEnv();
 
609
    mdb_size actualSize = 0;
 
610
    ioFile->Get(menv, y->mYarn_Buf, y->mYarn_Size, /*pos*/ 0, &actualSize);
 
611
    y->mYarn_Fill = actualSize;
 
612
    
 
613
    if ( y->mYarn_Buf && actualSize >= headSize && ev->Good() )
 
614
    {
 
615
      mork_u1* buf = (mork_u1*) y->mYarn_Buf;
 
616
      outBool = ( MORK_MEMCMP(morkWriter_kFileHeader, buf, headSize) == 0 );
 
617
    }
 
618
  }
 
619
  else
 
620
    ev->NilPointerError();
 
621
 
 
622
  return outBool;
 
623
}
 
624
 
 
625
// { ----- begin store methods -----
 
626
/*virtual*/ mdb_err
 
627
orkinFactory::CanOpenFileStore(
 
628
  nsIMdbEnv* mev, // context
 
629
  // const char* inFilePath, // the file to investigate
 
630
  // const mdbYarn* inFirst512Bytes,
 
631
  nsIMdbFile* ioFile, // db abstract file interface
 
632
  mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
 
633
  mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
 
634
  mdbYarn* outFormatVersion)
 
635
{
 
636
  mdb_bool canOpenAsStore = morkBool_kFalse;
 
637
  mdb_bool canOpenAsPort = morkBool_kFalse;
 
638
  if ( outFormatVersion )
 
639
  {
 
640
    outFormatVersion->mYarn_Fill = 0;
 
641
  }
 
642
  mdb_err outErr = 0;
 
643
  morkEnv* ev = this->CanUseFactory(mev,
 
644
    /*inMutable*/ morkBool_kFalse, &outErr);
 
645
  if ( ev )
 
646
  {
 
647
    if ( ioFile && outCanOpenAsStore )
 
648
    {
 
649
      // right now always say true; later we should look for magic patterns
 
650
      canOpenAsStore = this->CanOpenMorkTextFile(ev, ioFile);
 
651
      canOpenAsPort = canOpenAsStore;
 
652
    }
 
653
    else
 
654
      ev->NilPointerError();
 
655
    
 
656
    outErr = ev->AsErr();
 
657
  }
 
658
  if ( outCanOpenAsStore )
 
659
    *outCanOpenAsStore = canOpenAsStore;
 
660
    
 
661
  if ( outCanOpenAsPort )
 
662
    *outCanOpenAsPort = canOpenAsPort;
 
663
    
 
664
  return outErr;
 
665
}
 
666
  
 
667
/*virtual*/ mdb_err
 
668
orkinFactory::OpenFileStore( // open an existing database
 
669
  nsIMdbEnv* mev, // context
 
670
  nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
 
671
  // const char* inFilePath, // the file to open for general db usage
 
672
  nsIMdbFile* ioFile, // db abstract file interface
 
673
  const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
 
674
  nsIMdbThumb** acqThumb)
 
675
{
 
676
  mdb_err outErr = 0;
 
677
  nsIMdbThumb* outThumb = 0;
 
678
  morkEnv* ev = this->CanUseFactory(mev,
 
679
    /*inMutable*/ morkBool_kFalse, &outErr);
 
680
  if ( ev )
 
681
  {
 
682
    if ( !ioHeap ) // need to use heap from env?
 
683
      ioHeap = ev->mEnv_Heap;
 
684
    
 
685
    if ( ioFile && inOpenPolicy && acqThumb )
 
686
    {
 
687
      morkFactory* factory = (morkFactory*) this->mHandle_Object;
 
688
      morkStore* store = new(*ioHeap, ev)
 
689
        morkStore(ev, morkUsage::kHeap, ioHeap, factory, ioHeap);
 
690
        
 
691
      if ( store )
 
692
      {
 
693
        mork_bool frozen = morkBool_kFalse; // open store mutable access
 
694
        if ( store->OpenStoreFile(ev, frozen, ioFile, inOpenPolicy) )
 
695
        {
 
696
          morkThumb* thumb = morkThumb::Make_OpenFileStore(ev, ioHeap, store);
 
697
          if ( thumb )
 
698
          {
 
699
            outThumb = thumb;
 
700
            thumb->AddRef();
 
701
          }
 
702
        }
 
703
//        store->CutStrongRef(mev); // always cut ref (handle has its own ref)
 
704
      }
 
705
    }
 
706
    else
 
707
      ev->NilPointerError();
 
708
    
 
709
    outErr = ev->AsErr();
 
710
  }
 
711
  if ( acqThumb )
 
712
    *acqThumb = outThumb;
 
713
  return outErr;
 
714
}
 
715
// Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
 
716
// then call nsIMdbFactory::ThumbToOpenStore() to get the store instance.
 
717
  
 
718
/*virtual*/ mdb_err
 
719
orkinFactory::ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
 
720
  nsIMdbEnv* mev, // context
 
721
  nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status
 
722
  nsIMdbStore** acqStore)
 
723
{
 
724
  mdb_err outErr = 0;
 
725
  nsIMdbStore* outStore = 0;
 
726
  morkEnv* ev = this->CanUseFactory(mev,
 
727
    /*inMutable*/ morkBool_kFalse, &outErr);
 
728
  if ( ev )
 
729
  {
 
730
    if ( ioThumb && acqStore )
 
731
    {
 
732
      morkThumb* thumb = (morkThumb*) ioThumb;
 
733
      morkStore* store = thumb->ThumbToOpenStore(ev);
 
734
      if ( store )
 
735
      {
 
736
        store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
 
737
        store->mStore_CanDirty = morkBool_kTrue;
 
738
        store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue);
 
739
        
 
740
        outStore = store;
 
741
        NS_ADDREF(store);
 
742
      }
 
743
    }
 
744
    else
 
745
      ev->NilPointerError();
 
746
    
 
747
    outErr = ev->AsErr();
 
748
  }
 
749
  if ( acqStore )
 
750
    *acqStore = outStore;
 
751
  return outErr;
 
752
}
 
753
 
 
754
/*virtual*/ mdb_err
 
755
orkinFactory::CreateNewFileStore( // create a new db with minimal content
 
756
  nsIMdbEnv* mev, // context
 
757
  nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
 
758
  // const char* inFilePath, // name of file which should not yet exist
 
759
  nsIMdbFile* ioFile, // db abstract file interface
 
760
  const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
 
761
  nsIMdbStore** acqStore)
 
762
{
 
763
  mdb_err outErr = 0;
 
764
  nsIMdbStore* outStore = 0;
 
765
  morkEnv* ev = this->CanUseFactory(mev,
 
766
    /*inMutable*/ morkBool_kFalse, &outErr);
 
767
  if ( ev )
 
768
  {
 
769
    if ( !ioHeap ) // need to use heap from env?
 
770
      ioHeap = ev->mEnv_Heap;
 
771
    
 
772
    if ( ioFile && inOpenPolicy && acqStore && ioHeap )
 
773
    {
 
774
      morkFactory* factory = (morkFactory*) this->mHandle_Object;
 
775
      morkStore* store = new(*ioHeap, ev)
 
776
        morkStore(ev, morkUsage::kHeap, ioHeap, factory, ioHeap);
 
777
        
 
778
      if ( store )
 
779
      {
 
780
        store->mStore_CanAutoAssignAtomIdentity = morkBool_kTrue;
 
781
        store->mStore_CanDirty = morkBool_kTrue;
 
782
        store->SetStoreAndAllSpacesCanDirty(ev, morkBool_kTrue);
 
783
 
 
784
        if ( store->CreateStoreFile(ev, ioFile, inOpenPolicy) )
 
785
          outStore = store;
 
786
        NS_ADDREF(store);          
 
787
      }
 
788
    }
 
789
    else
 
790
      ev->NilPointerError();
 
791
    
 
792
    outErr = ev->AsErr();
 
793
  }
 
794
  if ( acqStore )
 
795
    *acqStore = outStore;
 
796
  return outErr;
 
797
}
 
798
// } ----- end store methods -----
 
799
 
 
800
// } ===== end nsIMdbFactory methods =====
 
801
 
 
802
 
 
803
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789