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

« back to all changes in this revision

Viewing changes to mozilla/db/mork/src/morkSink.h

  • 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 _MORKSINK_
 
40
#define _MORKSINK_ 1
 
41
 
 
42
#ifndef _MORK_
 
43
#include "mork.h"
 
44
#endif
 
45
 
 
46
#ifndef _MORKBLOB_
 
47
#include "morkBlob.h"
 
48
#endif
 
49
 
 
50
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
 
51
 
 
52
/*| morkSink is intended to be a very cheap buffered i/o sink which
 
53
**| writes to bufs and other strings a single byte at a time.  The
 
54
**| basic idea is that writing a single byte has a very cheap average
 
55
**| cost, because a polymophic function call need only occur when the
 
56
**| space between At and End is exhausted.  The rest of the time a
 
57
**| very cheap inline method will write a byte, and then bump a pointer.
 
58
**|
 
59
**|| At: the current position in some sequence of bytes at which to
 
60
**| write the next byte put into the sink.  Presumably At points into
 
61
**| the private storage of some space which is not yet filled (except
 
62
**| when At reaches End, and the overflow must then spill).  Note both
 
63
**| At and End are zeroed in the destructor to help show that a sink
 
64
**| is no longer usable; this is safe because At==End causes the case
 
65
**| where SpillPutc() is called to handled an exhausted buffer space.
 
66
**|
 
67
**|| End: an address one byte past the last byte which can be written
 
68
**| without needing to make a buffer larger than previously.  When At
 
69
**| and End are equal, this means there is no space to write a byte,
 
70
**| and that some underlying buffer space must be grown before another
 
71
**| byte can be written.  Note At must always be less than or equal to
 
72
**| End, and otherwise an important invariant has failed severely.
 
73
**|
 
74
**|| Buf: this original class slot has been commented out in the new
 
75
**| and more abstract version of this sink class, but the general idea
 
76
**| behind this slot should be explained to help design subclasses.
 
77
**| Each subclass should provide space into which At and End can point,
 
78
**| where End is beyond the last writable byte, and At is less than or
 
79
**| equal to this point inside the same buffer.  With some kinds of
 
80
**| medium, such as writing to an instance of morkBlob, it is feasible
 
81
**| to point directly into the final resting place for all the content
 
82
**| written to the medium.  Other mediums such as files, which write
 
83
**| only through function calls, will typically need a local buffer
 
84
**| to efficiently accumulate many bytes between such function calls.
 
85
**|
 
86
**|| FlushSink: this flush method should move any buffered content to 
 
87
**| it's final destination.  For example, for buffered writes to a
 
88
**| string medium, where string methods are function calls and not just
 
89
**| inline macros, it is faster to accumulate many bytes in a small
 
90
**| local buffer and then move these en masse later in a single call.
 
91
**|
 
92
**|| SpillPutc: when At is greater than or equal to End, this means an
 
93
**| underlying buffer has become full, so the buffer must be flushed
 
94
**| before a new byte can be written.  The intention is that SpillPutc()
 
95
**| will be equivalent to calling FlushSink() followed by another call
 
96
**| to Putc(), where the flush is expected to make At less then End once
 
97
**| again.  Except that FlushSink() need not make the underlying buffer
 
98
**| any larger, and SpillPutc() typically must make room for more bytes.
 
99
**| Note subclasses might want to guard against the case that both At
 
100
**| and End are null, which happens when a sink is destroyed, which sets
 
101
**| both these pointers to null as an indication the sink is disabled.
 
102
|*/
 
103
class morkSink {
 
104
    
 
105
// ````` ````` ````` `````   ````` ````` ````` `````  
 
106
public: // public sink virtual methods
 
107
 
 
108
  virtual void FlushSink(morkEnv* ev) = 0;
 
109
  virtual void SpillPutc(morkEnv* ev, int c) = 0;
 
110
 
 
111
// ````` ````` ````` `````   ````` ````` ````` `````  
 
112
public: // member variables
 
113
 
 
114
  mork_u1*     mSink_At;     // pointer into mSink_Buf
 
115
  mork_u1*     mSink_End;    // one byte past last content byte
 
116
 
 
117
// define morkSink_kBufSize 256 /* small enough to go on stack */
 
118
 
 
119
  // mork_u1      mSink_Buf[ morkSink_kBufSize + 4 ];
 
120
  // want plus one for any needed end null byte; use plus 4 for alignment
 
121
   
 
122
// ````` ````` ````` `````   ````` ````` ````` `````  
 
123
public: // public non-poly morkSink methods
 
124
 
 
125
  virtual ~morkSink(); // zero both At and End; virtual for subclasses
 
126
  morkSink() { } // does nothing; subclasses must set At and End suitably
 
127
 
 
128
  void Putc(morkEnv* ev, int c)
 
129
  { 
 
130
    if ( mSink_At < mSink_End )
 
131
      *mSink_At++ = (mork_u1) c;
 
132
    else
 
133
      this->SpillPutc(ev, c);
 
134
  }
 
135
};
 
136
 
 
137
/*| morkSpool: an output sink that efficiently writes individual bytes
 
138
**| or entire byte sequences to a coil instance, which grows as needed by
 
139
**| using the heap instance in the coil to grow the internal buffer.
 
140
**|
 
141
**|| Note we do not "own" the coil referenced by mSpool_Coil, and
 
142
**| the lifetime of the coil is expected to equal or exceed that of this
 
143
**| sink by some external means.  Typical usage might involve keeping an
 
144
**| instance of morkCoil and an instance of morkSpool in the same
 
145
**| owning parent object, which uses the spool with the associated coil.
 
146
|*/
 
147
class morkSpool : public morkSink { // for buffered i/o to a morkCoil
 
148
 
 
149
// ````` ````` ````` `````   ````` ````` ````` `````  
 
150
public: // public sink virtual methods
 
151
 
 
152
  // when morkSink::Putc() moves mSink_At, mSpool_Coil->mBuf_Fill is wrong:
 
153
 
 
154
  virtual void FlushSink(morkEnv* ev); // sync mSpool_Coil->mBuf_Fill
 
155
  virtual void SpillPutc(morkEnv* ev, int c); // grow coil and write byte
 
156
 
 
157
// ````` ````` ````` `````   ````` ````` ````` `````  
 
158
public: // member variables
 
159
  morkCoil*   mSpool_Coil; // destination medium for written bytes
 
160
    
 
161
// ````` ````` ````` `````   ````` ````` ````` `````  
 
162
public: // public non-poly morkSink methods
 
163
 
 
164
  static void BadSpoolCursorOrderError(morkEnv* ev);
 
165
  static void NilSpoolCoilError(morkEnv* ev);
 
166
 
 
167
  virtual ~morkSpool();
 
168
  // Zero all slots to show this sink is disabled, but destroy no memory.
 
169
  // Note it is typically unnecessary to flush this coil sink, since all
 
170
  // content is written directly to the coil without any buffering.
 
171
  
 
172
  morkSpool(morkEnv* ev, morkCoil* ioCoil);
 
173
  // After installing the coil, calls Seek(ev, 0) to prepare for writing.
 
174
  
 
175
  // ----- All boolean return values below are equal to ev->Good(): -----
 
176
 
 
177
  mork_bool Seek(morkEnv* ev, mork_pos inPos);
 
178
  // Changed the current write position in coil's buffer to inPos.
 
179
  // For example, to start writing the coil from scratch, use inPos==0.
 
180
 
 
181
  mork_bool Write(morkEnv* ev, const void* inBuf, mork_size inSize);
 
182
  // write inSize bytes of inBuf to current position inside coil's buffer
 
183
 
 
184
  mork_bool PutBuf(morkEnv* ev, const morkBuf& inBuffer)
 
185
  { return this->Write(ev, inBuffer.mBuf_Body, inBuffer.mBuf_Fill); }
 
186
  
 
187
  mork_bool PutString(morkEnv* ev, const char* inString);
 
188
  // call Write() with inBuf=inString and inSize=strlen(inString),
 
189
  // unless inString is null, in which case we then do nothing at all.
 
190
};
 
191
 
 
192
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
 
193
 
 
194
#endif /* _MORKSINK_ */