~ubuntu-branches/ubuntu/precise/xerces-c/precise-security

« back to all changes in this revision

Viewing changes to src/xercesc/framework/LocalFileFormatTarget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2009-12-05 14:58:32 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20091205145832-378dg3x72mdzfzup
Tags: 3.1.0~rc1-1
* New upstream release; public release candidate uploaded at request of
  upstream.
* Updated source format to '3.0 (quilt)'

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
6
 * (the "License"); you may not use this file except in compliance with
7
7
 * the License.  You may obtain a copy of the License at
8
 
 * 
 
8
 *
9
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 
 * 
 
10
 *
11
11
 * Unless required by applicable law or agreed to in writing, software
12
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
16
 */
17
17
 
18
18
/*
19
 
 * $Id: LocalFileFormatTarget.cpp 553937 2007-07-06 16:02:19Z amassari $
 
19
 * $Id: LocalFileFormatTarget.cpp 882597 2009-11-20 15:10:13Z borisk $
20
20
 */
21
21
 
22
22
#include <xercesc/framework/LocalFileFormatTarget.hpp>
28
28
 
29
29
XERCES_CPP_NAMESPACE_BEGIN
30
30
 
 
31
const XMLSize_t MAX_BUFFER_SIZE = 65536;
 
32
 
31
33
LocalFileFormatTarget::LocalFileFormatTarget( const XMLCh* const   fileName
32
34
                                            , MemoryManager* const manager)
33
35
: fSource(0)
34
36
, fDataBuf(0)
35
37
, fIndex(0)
36
 
, fCapacity(1023)
 
38
, fCapacity(1024)
37
39
, fMemoryManager(manager)
38
40
{
39
41
    fSource = XMLPlatformUtils::openFileToWrite(fileName, manager);
41
43
    if (fSource == (FileHandle) XERCES_Invalid_File_Handle)
42
44
        ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager);
43
45
 
44
 
    // Buffer is one larger than capacity, to allow for zero term
45
 
    fDataBuf = (XMLByte*) fMemoryManager->allocate
46
 
    (
47
 
        (fCapacity+4) * sizeof(XMLByte)
48
 
    );//new XMLByte[fCapacity+4];
49
 
 
50
 
    // Keep it null terminated
51
 
    fDataBuf[0] = XMLByte(0);
52
 
 
 
46
    fDataBuf = (XMLByte*) fMemoryManager->allocate (
 
47
      fCapacity * sizeof(XMLByte));
53
48
}
54
49
 
55
50
LocalFileFormatTarget::LocalFileFormatTarget( const char* const    fileName
57
52
: fSource(0)
58
53
, fDataBuf(0)
59
54
, fIndex(0)
60
 
, fCapacity(1023)
 
55
, fCapacity(1024)
61
56
, fMemoryManager(manager)
62
57
{
63
58
    fSource = XMLPlatformUtils::openFileToWrite(fileName, manager);
65
60
    if (fSource == (FileHandle) XERCES_Invalid_File_Handle)
66
61
        ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager);
67
62
 
68
 
    // Buffer is one larger than capacity, to allow for zero term
69
 
    fDataBuf = (XMLByte*) fMemoryManager->allocate
70
 
    (
71
 
        (fCapacity+4) * sizeof(XMLByte)
72
 
    );//new XMLByte[fCapacity+4];
73
 
 
74
 
    // Keep it null terminated
75
 
    fDataBuf[0] = XMLByte(0);
 
63
    fDataBuf = (XMLByte*) fMemoryManager->allocate (
 
64
      fCapacity * sizeof(XMLByte));
76
65
}
77
66
 
78
67
LocalFileFormatTarget::~LocalFileFormatTarget()
79
68
{
80
 
    // flush remaining buffer before destroy
81
 
    flushBuffer();
 
69
    try
 
70
    {
 
71
        // flush remaining buffer before destroy
 
72
        XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
82
73
 
83
 
    if (fSource)
84
 
        XMLPlatformUtils::closeFile(fSource, fMemoryManager);
 
74
        if (fSource)
 
75
          XMLPlatformUtils::closeFile(fSource, fMemoryManager);
 
76
    }
 
77
    catch (...)
 
78
    {
 
79
      // There is nothing we can do about it here.
 
80
    }
85
81
 
86
82
    fMemoryManager->deallocate(fDataBuf);//delete [] fDataBuf;
87
83
}
88
84
 
89
85
void LocalFileFormatTarget::flush()
90
86
{
91
 
    flushBuffer();
 
87
  XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
 
88
  fIndex = 0;
92
89
}
93
90
 
94
91
void LocalFileFormatTarget::writeChars(const XMLByte* const toWrite
95
 
                                     , const XMLSize_t      count
96
 
                                     , XMLFormatter * const        )
 
92
                                     , const XMLSize_t count
 
93
                                     , XMLFormatter * const)
97
94
{
98
 
    if (count) {
99
 
        if (insureCapacity(count))
100
 
        {
101
 
            memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte));
102
 
            fIndex += count;
103
 
        }
104
 
        else
105
 
        {
106
 
            //flush whatever we have in the buffer and the incoming byte stream
107
 
            flushBuffer();
108
 
            XMLPlatformUtils::writeBufferToFile(fSource, count, toWrite, fMemoryManager);
109
 
        }
 
95
    if (count)
 
96
    {
 
97
      if (count < MAX_BUFFER_SIZE)
 
98
      {
 
99
        // If we don't have enough space, see if we can grow the buffer.
 
100
        //
 
101
        if (fIndex + count > fCapacity && fCapacity < MAX_BUFFER_SIZE)
 
102
          insureCapacity (count);
 
103
 
 
104
        // If still not enough space, flush the buffer.
 
105
        //
 
106
        if (fIndex + count > fCapacity)
 
107
        {
 
108
          XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
 
109
          fIndex = 0;
 
110
        }
 
111
 
 
112
        memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte));
 
113
        fIndex += count;
 
114
      }
 
115
      else
 
116
      {
 
117
        if (fIndex)
 
118
        {
 
119
          XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
 
120
          fIndex = 0;
 
121
        }
 
122
 
 
123
        XMLPlatformUtils::writeBufferToFile(fSource, count, toWrite, fMemoryManager);
 
124
      }
110
125
    }
111
126
 
112
127
    return;
113
128
}
114
129
 
115
 
void LocalFileFormatTarget::flushBuffer()
116
 
{
117
 
    // Exception thrown in writeBufferToFile, if any, will be propagated to
118
 
    // the XMLFormatter and then to the DOMLSSerializer, which may notify
119
 
    // application through DOMErrorHandler, if any.
120
 
    XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
121
 
    fIndex = 0;
122
 
    fDataBuf[0] = 0;
123
 
    fDataBuf[fIndex + 1] = 0;
124
 
    fDataBuf[fIndex + 2] = 0;
125
 
    fDataBuf[fIndex + 3] = 0;
126
 
}
127
 
 
128
 
/***
129
 
 *
130
 
 *   if the current capacity is not enough, and we can not have
131
 
 *   enough memory for the new buffer, we got to notify the caller 
132
 
 *
133
 
 ***/
134
 
bool LocalFileFormatTarget::insureCapacity(const XMLSize_t extraNeeded)
135
 
{
136
 
    // If we can handle it, do nothing yet
137
 
    if (fIndex + extraNeeded < fCapacity)
138
 
        return true;
139
 
 
140
 
    // Oops, not enough room. Calc new capacity and allocate new buffer
141
 
    const XMLSize_t newCap = ((fIndex + extraNeeded) * 2);
142
 
    XMLByte* newBuf = 0;
143
 
 
144
 
    try
145
 
    {
146
 
        newBuf = (XMLByte*) fMemoryManager->allocate
147
 
        (
148
 
            (newCap+4) * sizeof(XMLByte)
149
 
        );//new XMLByte[newCap+4];
150
 
    }
151
 
    catch(const OutOfMemoryException&)
152
 
    {
153
 
        return false;
154
 
    }
155
 
 
156
 
    assert(newBuf);
 
130
void LocalFileFormatTarget::insureCapacity(const XMLSize_t extraNeeded)
 
131
{
 
132
    XMLSize_t newCap = fCapacity * 2;
 
133
 
 
134
    while (fIndex + extraNeeded > newCap)
 
135
      newCap *= 2;
 
136
 
 
137
    XMLByte* newBuf  = (XMLByte*) fMemoryManager->allocate (
 
138
      newCap * sizeof(XMLByte));
157
139
 
158
140
    // Copy over the old stuff
159
 
    memcpy(newBuf, fDataBuf, fCapacity * sizeof(XMLByte) + 4);
 
141
    memcpy(newBuf, fDataBuf, fIndex * sizeof(XMLByte));
160
142
 
161
143
    // Clean up old buffer and store new stuff
162
 
    fMemoryManager->deallocate(fDataBuf); //delete [] fDataBuf;
 
144
    fMemoryManager->deallocate(fDataBuf);
163
145
    fDataBuf = newBuf;
164
146
    fCapacity = newCap;
165
 
 
166
 
    // flush the buffer too
167
 
    flushBuffer();
168
 
    return true;
169
147
}
170
148
 
171
149
XERCES_CPP_NAMESPACE_END
172
 
 
173