root/OpenSceneGraph/trunk/src/osgPlugins/txp/trpage_writebuf.cpp @ 13041

Revision 13041, 9.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* ************************
2   Copyright Terrain Experts Inc.
3   Terrain Experts Inc (TERREX) reserves all rights to this source code
4   unless otherwise specified in writing by the President of TERREX.
5   This copyright may be updated in the future, in which case that version
6   supercedes this one.
7   -------------------
8   Terrex Experts Inc.
9   4400 East Broadway #314
10   Tucson, AZ  85711
11   info@terrex.com
12   Tel: (520) 323-7990
13   ************************
14   */
15
16#include <osgDB/FileUtils>
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <string.h>
21
22/* trpage_writebuf.cpp
23    This source file contains the implementation of trpgMemWriteBuffer.
24    That is a subclass of trpgWriteBuffer, which implements an interface
25    definition for an object which can accept data to be written.
26    The Mem version is used to write (for example) a tile's worth of data.
27    That data can then be written to a file (or sent over the network).
28    You should not need to change this implementation.  Simply sublcass
29    trpgWriteBuffer and implement all of the required methods.  The
30    resulting class can then be used in all the places a trpgWriteBuffer
31    is required.
32    */
33
34#include <trpage_io.h>
35#include <trpage_swap.h>
36
37/* **********************
38   Memory Write Buffer functions
39   **********************
40   */
41// Constructor
42trpgMemWriteBuffer::trpgMemWriteBuffer(trpgEndian in_ness)
43{
44    ness = in_ness;
45    cpuNess = trpg_cpu_byte_order();
46    data = NULL;
47    curLen = totLen = 0;
48}
49
50// Destructor
51trpgMemWriteBuffer::~trpgMemWriteBuffer()
52{
53    if (data)
54        delete [] data;
55    data = NULL;
56}
57
58/* Length()
59    Return the length of the given buffer.
60    */
61int trpgMemWriteBuffer::length() const
62{
63    return curLen;
64}
65
66/* getData()
67    Return a pointer to the memory buffer.
68    */
69const char *trpgMemWriteBuffer::getData() const
70{
71    return data;
72}
73
74/* Length()
75    Set the maximum buffer length.
76    */
77void trpgMemWriteBuffer::setLength(unsigned int len)
78{
79    if ((int)len > totLen) {
80        char *old_data = data;
81        int oldLen = totLen;
82        totLen = 2*len;
83        data = new char[totLen];
84
85        if (old_data) {
86            memcpy(data,old_data,oldLen);
87            delete [] old_data;
88        }
89    }
90}
91
92/* append()
93    Append the given data to our buffer.
94    */
95void trpgMemWriteBuffer::append(unsigned int len,const char *val)
96{
97    if (len == 0)  return;
98    setLength(curLen+len);
99    memcpy(&data[curLen],val,len);
100    curLen += len;
101}
102
103/* set()
104    Set a specific portion of the buffer to a given value.
105    */
106void trpgMemWriteBuffer::set(unsigned int pos,unsigned int len,const char *val)
107{
108    if (len == 0) return;
109    if (pos+len > (unsigned int)curLen) return;
110
111    memcpy(&data[pos],val,len);
112}
113
114/* --- replacement virtual functions --- */
115
116/* Reset()
117    Drop whatever's being stored.
118    */
119void trpgMemWriteBuffer::Reset()
120{
121    curLen = 0;
122}
123
124// Add(Int32)
125void trpgMemWriteBuffer::Add(int32 val)
126{
127    if (ness != cpuNess)
128        val = trpg_byteswap_int(val);
129    append(sizeof(int32),(const char *)&val);
130}
131
132// Add(int64)
133void trpgMemWriteBuffer::Add(int64 val)
134{
135    if (ness != cpuNess)
136        val = trpg_byteswap_llong(val);
137    append(sizeof(int64),(const char *)&val);
138}
139
140// Add(string)
141// [len] [value...]
142void trpgMemWriteBuffer::Add(const char *val)
143{
144    int32 len = (val ? strlen(val) : 0),vlen = len;
145    if (ness != cpuNess)
146        vlen = trpg_byteswap_int(vlen);
147    append(sizeof(int32),(const char *)&vlen);
148    append(len,val);
149}
150
151// Add(std::string)
152void trpgMemWriteBuffer::Add(std::string &val)
153{
154    Add(val.c_str());
155}
156
157// Add(float32)
158void trpgMemWriteBuffer::Add(float32 val)
159{
160    char cval[4];
161    if (ness != cpuNess)
162        trpg_byteswap_float_to_4bytes(val,cval);
163    else
164        memcpy(cval,&val,4);
165
166    append(sizeof(float32),cval);
167}
168
169// Add(float64)
170void trpgMemWriteBuffer::Add(float64 val)
171{
172    char cval[8];
173    if (ness != cpuNess)
174        trpg_byteswap_double_to_8bytes(val,cval);
175    else
176        memcpy(cval,&val,8);
177
178    append(sizeof(float64),cval);
179}
180
181// Add(int8)
182void trpgMemWriteBuffer::Add(uint8 val)
183{
184    // No byte swapping needed
185    append(sizeof(uint8),(const char *)&val);
186}
187
188//#if (bool != int32)
189// Add(bool)
190void trpgMemWriteBuffer::Add(bool val)
191{
192    uint8 ival;
193
194    ival = (val ? 1 : 0);
195    Add(ival);
196}
197//#endif
198
199#if (trpgDiskRef != int64)
200// Add(trpgDiskRef)
201void trpgMemWriteBuffer::Add(trpgDiskRef val)
202{
203    if (ness != cpuNess)
204        val = trpg_byteswap_llong(val);
205
206    append(sizeof(trpgDiskRef),(const char *)&val);
207}
208#endif
209
210// Add(trpgToken)
211void trpgMemWriteBuffer::Add(trpgToken val)
212{
213    if (ness != cpuNess)
214        val = trpg_byteswap_short(val);
215
216    append(sizeof(trpgToken),(const char *)&val);
217}
218
219// Add(tx2iPoint)
220void trpgWriteBuffer::Add(const trpg2iPoint &val)
221{
222    Add((int32)val.x);
223    Add((int32)val.y);
224}
225
226// Add(tx2dPoint)
227void trpgWriteBuffer::Add(const trpg2dPoint &val)
228{
229    Add((float64)val.x);
230    Add((float64)val.y);
231}
232
233// Add(trpg3dPoint)
234void trpgWriteBuffer::Add(const trpg3dPoint &val)
235{
236    Add((float64)val.x);
237    Add((float64)val.y);
238    Add((float64)val.z);
239}
240
241// Add(trpgColor)
242void trpgWriteBuffer::Add(const trpgColor &val)
243{
244    Add(val.red);
245    Add(val.green);
246    Add(val.blue);
247}
248
249// Add(std::string)
250void trpgWriteBuffer::Add(const std::string &val)
251{
252    Add(val.c_str());
253}
254
255/* Push()
256    Starts defining a new object.
257    Need to keep track of where length goes.
258    */
259void trpgMemWriteBuffer::Begin(trpgToken tok)
260{
261    Add(tok);
262    lengths.push_back(curLen);
263    Add((int32)0);
264}
265
266/* Push()
267    Pushes a level on the stack.  For defining children.
268    */
269void trpgMemWriteBuffer::Push()
270{
271    Add((trpgToken)TRPG_PUSH);
272}
273
274/* Pop()
275    Pops a level off the "stack".
276    */
277void trpgMemWriteBuffer::Pop()
278{
279    Add((trpgToken)TRPG_POP);
280}
281
282/* Will take out a pop from the end of the  buffer, if there is one */
283bool trpgMemWriteBuffer::UnPop()
284{
285   //Check to see if there is a pop token ant the end
286   trpgToken tk;
287   memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));
288   if(tk == TRPG_POP)
289   {
290      curLen -= sizeof(trpgToken);
291      return true;
292   }
293   else
294      return false;
295}
296/* Will take out a push from the end of the  buffer, if there is one */
297bool trpgMemWriteBuffer::UnPush()
298{
299   //Check to see if there is a push token ant the end
300   trpgToken tk;
301   memcpy(&tk, &data[curLen - sizeof(trpgToken)], sizeof(trpgToken));
302   if(tk == TRPG_PUSH)
303   {
304      curLen -= sizeof(trpgToken);
305      return true;
306   }
307   else
308      return false;
309}
310
311/* End()
312    Finished defining an object.
313    Write the length out where appropriate.
314    */
315void trpgMemWriteBuffer::End()
316{
317    if (lengths.size() == 0)
318        // Note: say something clever here
319        return;
320
321    int id = lengths.size()-1;
322    int32 len = curLen - lengths[id];
323    int32 rlen = len-sizeof(int32);
324    if (ness != cpuNess)
325        rlen = trpg_byteswap_int(rlen);
326    set(curLen - len,sizeof(int32),(const char *)&rlen);
327    lengths.resize(id);
328}
329
330/* Appendable File
331    This class is used as a simple appendable file.  It's used
332    for dumping tile and texture (or most anything) into.
333 */
334
335trpgwAppFile::trpgwAppFile(trpgEndian inNess,const char *fileName,bool reuse)
336{
337    Init(inNess,fileName,reuse);
338}
339
340void trpgwAppFile::Init(trpgEndian inNess,const char *fileName,bool reuse)
341{
342    valid = false;
343    ness = inNess;
344    cpuNess = trpg_cpu_byte_order();
345
346    if (reuse==false) {
347        if (!(fp = osgDB::fopen(fileName,"wb")))
348            return;
349        lengthSoFar = 0;
350        valid = true;
351    } else {
352        if (!(fp = osgDB::fopen(fileName,"ab")))
353            return;
354        // ftell is still zero, dammit.  Arg.
355        fseek(fp,0,SEEK_END);
356        lengthSoFar = ftell(fp);
357        valid = true;
358    }
359}
360
361trpgwAppFile::~trpgwAppFile()
362{
363    if (fp)
364        fclose(fp);
365    valid = false;
366}
367
368// Return the amount of data written so far (in total)
369int trpgwAppFile::GetLengthWritten()
370{
371    return lengthSoFar;
372}
373
374// Append the given buffer to our appendable file
375bool trpgwAppFile::Append(const trpgMemWriteBuffer *buf1,const trpgMemWriteBuffer *buf2)
376{
377    if (!isValid()) return false;
378
379    // Get the total length
380    int totLen = buf1->length() + (buf2 ? buf2->length() : 0);
381
382    // Write the length out
383    if (fwrite(&totLen,sizeof(int32),1,fp) != 1) {
384        valid = false;
385        return false;
386    }
387
388    // Write the data out
389    const char *data = buf1->getData();
390    unsigned int len = buf1->length();
391    if (fwrite(data,sizeof(char),len,fp) != len) {
392        valid = false;
393        return false;
394    }
395    if (buf2) {
396        data = buf2->getData();
397        len = buf2->length();
398        if (fwrite(data,sizeof(char),len,fp) != len) {
399            valid = false;
400            return false;
401        }
402    }
403
404    lengthSoFar += totLen;
405
406    return true;
407}
408
409// Append the given raw data to our appendable file
410bool trpgwAppFile::Append(const char *data,int size)
411{
412    if (!isValid()) return false;
413
414    if (!data)
415        return false;
416
417    // Write the length out
418    if (fwrite(&size,sizeof(int32),1,fp) != 1) {
419        valid = false;
420        return false;
421    }
422
423    // Write the data out
424    if (fwrite(data,sizeof(char),size,fp) != (size_t)size) {
425        valid = false;
426        return false;
427    }
428
429    lengthSoFar += size;
430
431    return true;
432}
433
434// Flushes the current tile file
435bool trpgwAppFile::Flush()
436{
437    // Flush the File *
438    if (fp)
439        fflush(fp);
440
441    return true;
442}
443
444// Return the current file position
445int64 trpgwAppFile::Pos() const
446{
447    if (!isValid())
448        return 0;
449
450    // Note: This means an appendable file is capped at 2GB
451    long pos = ftell(fp);
452
453    return pos;
454}
455
456// Validity check
457bool trpgwAppFile::isValid() const
458{
459    return valid;
460}
Note: See TracBrowser for help on using the browser.