diff options
Diffstat (limited to 'src/io')
| -rw-r--r-- | src/io/.cvsignore | 5 | ||||
| -rw-r--r-- | src/io/Makefile.tst | 47 | ||||
| -rw-r--r-- | src/io/Makefile_insert | 29 | ||||
| -rw-r--r-- | src/io/base64stream.cpp | 315 | ||||
| -rw-r--r-- | src/io/base64stream.h | 122 | ||||
| -rw-r--r-- | src/io/crystalegg.xml | 769 | ||||
| -rw-r--r-- | src/io/doc2html.xsl | 63 | ||||
| -rw-r--r-- | src/io/ftos.cpp | 482 | ||||
| -rw-r--r-- | src/io/ftos.h | 54 | ||||
| -rw-r--r-- | src/io/gzipstream.cpp | 458 | ||||
| -rw-r--r-- | src/io/gzipstream.h | 121 | ||||
| -rw-r--r-- | src/io/inkscapestream.cpp | 842 | ||||
| -rw-r--r-- | src/io/inkscapestream.h | 669 | ||||
| -rw-r--r-- | src/io/makefile.in | 17 | ||||
| -rw-r--r-- | src/io/simple-sax.cpp | 1493 | ||||
| -rw-r--r-- | src/io/simple-sax.h | 97 | ||||
| -rw-r--r-- | src/io/streamtest.cpp | 244 | ||||
| -rw-r--r-- | src/io/stringstream.cpp | 128 | ||||
| -rw-r--r-- | src/io/stringstream.h | 96 | ||||
| -rw-r--r-- | src/io/sys.cpp | 300 | ||||
| -rw-r--r-- | src/io/sys.h | 51 | ||||
| -rw-r--r-- | src/io/uristream.cpp | 499 | ||||
| -rw-r--r-- | src/io/uristream.h | 173 | ||||
| -rw-r--r-- | src/io/xsltstream.cpp | 220 | ||||
| -rw-r--r-- | src/io/xsltstream.h | 124 |
25 files changed, 7418 insertions, 0 deletions
diff --git a/src/io/.cvsignore b/src/io/.cvsignore new file mode 100644 index 000000000..a437e318b --- /dev/null +++ b/src/io/.cvsignore @@ -0,0 +1,5 @@ +.deps +.dirstamp +.libs +makefile +streamtest diff --git a/src/io/Makefile.tst b/src/io/Makefile.tst new file mode 100644 index 000000000..1d6789fd2 --- /dev/null +++ b/src/io/Makefile.tst @@ -0,0 +1,47 @@ +############################################## +# +# Test makefile for InkscapeStreams +# +############################################## + + +CC = gcc +CXX = g++ + + +INC = -I. -I.. + +XSLT_CFLAGS = `pkg-config --cflags libxslt` +XSLT_LIBS = `pkg-config --libs libxslt` + +GLIBMM_CFLAGS = `pkg-config --cflags glibmm-2.4` +GLIBMM_LIBS = `pkg-config --libs glibmm-2.4` + +CFLAGS = -g $(GLIBMM_CFLAGS) $(XSLT_CFLAGS) +LIBS = $(GLIBMM_LIBS) $(XSLT_LIBS) ../uri.o -lz + +OBJ = \ +inkscapestream.o \ +base64stream.o \ +gzipstream.o \ +stringstream.o \ +uristream.o \ +xsltstream.o \ +ftos.o + +all: streamtest + +streamtest: inkscapestream.h libstream.a streamtest.o + $(CXX) -o streamtest streamtest.o libstream.a $(LIBS) + +libstream.a: $(OBJ) + ar crv libstream.a $(OBJ) + + +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + -$(RM) *.o *.a + -$(RM) streamtest + diff --git a/src/io/Makefile_insert b/src/io/Makefile_insert new file mode 100644 index 000000000..57978d678 --- /dev/null +++ b/src/io/Makefile_insert @@ -0,0 +1,29 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +io/all: io/libio.a + +io/clean: + rm -f io/libio.a $(io_libio_a_OBJECTS) + +io_libio_a_SOURCES = \ + io/base64stream.h \ + io/base64stream.cpp \ + io/ftos.cpp \ + io/ftos.h \ + io/gzipstream.cpp \ + io/gzipstream.h \ + io/inkscapestream.cpp \ + io/inkscapestream.h \ + io/simple-sax.cpp \ + io/simple-sax.h \ + io/stringstream.cpp \ + io/stringstream.h \ + io/sys.h \ + io/sys.cpp \ + io/uristream.cpp \ + io/uristream.h \ + io/xsltstream.cpp \ + io/xsltstream.h + +#io_streamtest_SOURCES = io/streamtest.cpp +#io_streamtest_LDADD = $(all_libs) diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp new file mode 100644 index 000000000..e9f8fe2a2 --- /dev/null +++ b/src/io/base64stream.cpp @@ -0,0 +1,315 @@ +/** + * Base64-enabled input and output streams + * + * This class allows easy encoding and decoding + * of Base64 data with a stream interface, hiding + * the implementation from the user. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "base64stream.h" + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B A S E 6 4 I N P U T S T R E A M +//######################################################################### + +static int base64decode[] = +{ +/*00*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*10*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*20*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*28*/ -1, -1, -1, 62, -1, -1, -1, 63, +/*30*/ 52, 53, 54, 55, 56, 57, 58, 59, +/*38*/ 60, 61, -1, -1, -1, -1, -1, -1, +/*40*/ -1, 0, 1, 2, 3, 4, 5, 6, +/*48*/ 7, 8, 9, 10, 11, 12, 13, 14, +/*50*/ 15, 16, 17, 18, 19, 20, 21, 22, +/*58*/ 23, 24, 25, -1, -1, -1, -1, -1, +/*60*/ -1, 26, 27, 28, 29, 30, 31, 32, +/*68*/ 33, 34, 35, 36, 37, 38, 39, 40, +/*70*/ 41, 42, 43, 44, 45, 46, 47, 48, +/*78*/ 49, 50, 51, -1, -1, -1, -1, -1 +}; + + +/** + * + */ +Base64InputStream::Base64InputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream) +{ + outCount = 0; + padCount = 0; + closed = false; + done = false; +} + +/** + * + */ +Base64InputStream::~Base64InputStream() +{ + close(); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int Base64InputStream::available() +{ + if (closed ) + return 0; + int len = source.available() * 2 / 3; + return len; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void Base64InputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int Base64InputStream::get() +{ + if (closed) + return -1; + + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + if (done) + return -1; + + int inBytes[4]; + int inCount = 0; + while (inCount < 4) + { + int ch = source.get(); + if (ch < 0) + { + while (inCount < 4) //pad if needed + { + inBytes[inCount++] = 0; + padCount++; + } + done = true; + break; + } + if (isspace(ch)) //ascii whitespace + { + //nothing + } + else if (ch == '=') //padding + { + inBytes[inCount++] = 0; + padCount++; + } + else + { + int byteVal = base64decode[ch & 0x7f]; + //printf("char:%c %d\n", ch, byteVal); + if (byteVal < 0) + { + //Bad lookup value + } + inBytes[inCount++] = byteVal; + } + } + + outBytes[0] = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03); + outBytes[1] = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f); + outBytes[2] = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f); + + outCount = 3; + + //try again + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + return -1; + +} + + +//######################################################################### +//# B A S E 6 4 O U T P U T S T R E A M +//######################################################################### + +static char *base64encode = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * + */ +Base64OutputStream::Base64OutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + column = 0; + columnWidth = 72; + outBuf = 0L; + bitCount = 0; +} + +/** + * + */ +Base64OutputStream::~Base64OutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void Base64OutputStream::close() +{ + if (closed) + return; + + //get any last bytes (1 or 2) out of the buffer + if (bitCount == 16) + { + outBuf <<= 2; //pad to make 18 bits + + int indx = (int)((outBuf & 0x0003f000L) >> 12); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + } + else if (bitCount == 8) + { + outBuf <<= 4; //pad to make 12 bits + + int indx = (int)((outBuf & 0x00000fc0L) >> 6); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + putCh('='); + } + + if (columnWidth > 0) //if <=0, no newlines + destination.put('\n'); + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void Base64OutputStream::flush() +{ + if (closed) + return; + //dont flush here. do it on close() + destination.flush(); +} + +/** + * Private. Put a char to the output stream, checking for line length + */ +void Base64OutputStream::putCh(int ch) +{ + destination.put(ch); + column++; + if (columnWidth > 0 && column >= columnWidth) + { + destination.put('\n'); + column = 0; + } +} + + +/** + * Writes the specified byte to this output stream. + */ +void Base64OutputStream::put(int ch) +{ + if (closed) + { + //probably throw an exception here + return; + } + + outBuf <<= 8; + outBuf |= (ch & 0xff); + bitCount += 8; + if (bitCount >= 24) + { + int indx = (int)((outBuf & 0x00fc0000L) >> 18); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0003f000L) >> 12); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + bitCount = 0; + outBuf = 0L; + } +} + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/base64stream.h b/src/io/base64stream.h new file mode 100644 index 000000000..7bfe73e5f --- /dev/null +++ b/src/io/base64stream.h @@ -0,0 +1,122 @@ +#ifndef __INKSCAPE_IO_BASE64STREAM_H__ +#define __INKSCAPE_IO_BASE64STREAM_H__ + +/** + * Base64-enabled input and output streams + * + * This class allows easy encoding and decoding + * of Base64 data with a stream interface, hiding + * the implementation from the user. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B A S E 6 4 I N P U T S T R E A M +//######################################################################### + +/** + * This class is for decoding a Base-64 encoded InputStream source + * + */ +class Base64InputStream : public BasicInputStream +{ + +public: + + Base64InputStream(InputStream &sourceStream); + + virtual ~Base64InputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + int outBytes[3]; + + int outCount; + + int padCount; + + bool done; + +}; // class Base64InputStream + + + + +//######################################################################### +//# B A S E 6 4 O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for Base-64 encoding data going to the + * destination OutputStream + * + */ +class Base64OutputStream : public BasicOutputStream +{ + +public: + + Base64OutputStream(OutputStream &destinationStream); + + virtual ~Base64OutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + + /** + * Sets the maximum line length for base64 output. If + * set to <=0, then there will be no line breaks; + */ + virtual void setColumnWidth(int val) + { columnWidth = val; } + +private: + + void putCh(int ch); + + int column; + + int columnWidth; + + unsigned long outBuf; + + int bitCount; + +}; // class Base64OutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_BASE64STREAM_H__ */ diff --git a/src/io/crystalegg.xml b/src/io/crystalegg.xml new file mode 100644 index 000000000..a94220c28 --- /dev/null +++ b/src/io/crystalegg.xml @@ -0,0 +1,769 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> +<book> + +<bookinfo> + <title>The Crystal Egg</title> + <author><firstname>H. G.</firstname><surname>Wells</surname></author> +</bookinfo> + + +<chapter> + +<para> + There was, until a year ago, a little and very grimy-looking shop +near Seven Dials over which, in weather-worn yellow lettering, the name +of "C. Cave, Naturalist and Dealer in Antiquities," was inscribed. The +contents of its window were curiously variegated. They comprised some +elephant tusks and an imperfect set of chessmen, beads and weapons, a +box of eyes, two skulls of tigers and one human, several moth-eaten +stuffed monkeys (one holding a lamp), an old-fashioned cabinet, a +flyblown ostrich egg or so, some fishing-tackle, and an extraordinarily +dirty, empty glass fish tank. There was also, at the moment the story +begins, a mass of crystal, worked into the shape of an egg and +brilliantly polished. And at that two people, who stood outside the +window, were looking, one of them a tall, thin clergyman, the other a +black-bearded young man of dusky complexion and unobtrusive costume. The +dusky young man spoke with eager gestulation, and seemed anxious for his +companion to purchase the article. +</para> + +<para> + While they were there, Mr. Cave came into his shop, his beard still +wagging with the bread and butter of his tea. When he saw these men and +the object of their regard, his countenance fell. He glanced guiltily +over his shoulder, and softly shut the door. He was a little old man, +with pale face and peculiar watery blue eyes; his hair was a dirty grey, +and he wore a shabby blue frock-coat, an ancient silk hat, and carpet +slippers very much down at heel. He remained watching the two men as +they talked. The clergyman went deep into his trouser pocket, examined a +handful of money, and showed his teeth in an agreeable smile. Mr. Cave +seemed still more depressed when they came into the shop. +</para> + +<para> + The clergyman, without any ceremony, asked the price of the crystal +egg. Mr. Cave glanced nervously towards the door leading into the +parlour, and said five pounds. The clergyman protested that the price +was high, to his companion as well as to Mr. Cave -- it was, indeed, +very much more than Mr. Cave had intended to ask, when he had stocked +the article -- and an attempt at bargaining ensued. Mr. Cave stepped to +the shop-door, and held it open. "Five pounds is my price," he said, as +though he wished to save himself the trouble of unprofitable discussion. +As he did so, the upper portion of a woman's face appeared above the +blind in the glass upper panel of the door leading into the parlour, and +stared curiously at the two customers. "Five pounds is my price," said +Mr. Cave, with a quiver in his voice. +</para> + +<para> + The swarthy young man had so far remained a spectator, watching Cave +keenly. Now he spoke. "Give him five pounds," he said. The clergyman +glanced at him to see if he were in earnest, and, when he looked at Mr. +Cave again, he saw that the latter's face was white. "It's a lot of +money," said the clergyman, and, diving into his pocket, began counting +his resources. He had little more than thirty shillings, and he appealed +to his companion, with whom he seemed to be on terms of considerable +intimacy. This gave Mr. Cave an opportunity of collecting his thoughts, +and he began to explain in an agitated manner that the crystal was not, +as a matter of fact, entirely free for sale. His two customers were +naturally surprised at this, and inquired why he had not thought of that +before he began to bargain. Mr. Cave became confused, but he stuck to +his story, that the crystal was not in the market that afternoon, that a +probable purchaser of it had already appeared. The two, treating this as +an attempt to raise the price still further, made as if they would leave +the shop. But at this point the parlour door opened, and the owner of +the dark fringe and the little eyes appeared. +</para> + +<para> + She was a coarse-featured, corpulent woman, younger and very much +larger than Mr. Cave; she walked heavily, and her face was flushed. +"That crystal is for sale, she said. "And five pounds is a good enough +price for it. I can't think what you're about, Cave, not to take the +gentleman's offer!" +</para> + +<para> + Mr. Cave, greatly perturbed by the irruption, looked angrily at her +over the rims of his spectacles, and, without excessive assurance, +asserted his right to manage his business in his own way. An altercation +began. The two customers watched the scene with interest and some +amusement, occasionally assisting Mrs. Cave with suggestions. Mr. Cave, +hard driven, persisted in a confused and impossible story of an enquiry +for the crystal that morning, and his agitation became painful. But he +stuck to his point with extraordinary persistence. +It was the young Oriental who ended this curious controversy. He +proposed that they should call again in the course of two days -- so as +to give the alleged enquirer a fair chance. "And then we must insist," +said the clergyman. "Five pounds." Mrs. Cave took it on herself to +apologise for her husband, explaining that he was sometimes "a little +odd," and as the two customers left, the couple prepared for a free +discussion of the incident in all its bearings. +</para> + +<para> + Mrs. Cave talked to her husband with singular directness. The poor +little man, quivering with emotion, muddled himself between his stories, +maintaining on the one hand that he had another customer in view, and on +the other asserting that the crystal was honestly worth ten guineas. +"Why did you ask five pounds?" said his wife. "Do let me manage my +business my own way!" said Mr. Cave. +</para> + +<para> + Mr. Cave had living with him a step-daughter and a step-son, and at +supper that night the transaction was re-discussed. None of them had a +high opinion of Mr. Cave's business methods, and this action seemed a +culminating folly. +</para> + +<para> + "It's my opinion he's refused that crystal before," said the +step-son, a loose-limbed lout of eighteen. +</para> + +<para> + "But Five Pounds!" said the step-daughter, an argumentative young +woman of six-and-twenty. +</para> + +<para> + Mr. Cave's answers were wretched; he could only mumble weak +assertions that he knew his own business best. They drove him from his +half-eaten supper into the shop, to close it for the night, his ears +aflame and tears of vexation behind his spectacles. "Why had he left the +crystal in the window so long? The folly of it!" That was the trouble +closest in his mind. For a time he could see no way of evading sale. +</para> + +<para> + After supper his step-daughter and step-son smartened themselves up +and went out and his wife retired upstairs to reflect upon the business +aspects of the crystal, over a little sugar and lemon and so forth in +hot water. Mr. Cave went into the shop, and stayed there until late, +ostensibly to make ornamental rockeries for gold-fish cases but really +for a private purpose that will be better explained later. The next day +Mrs. Cave found that the crystal had been removed from the window, and +was lying behind some second-hand books on angling. She replaced it in a +conspicuous position. But she did not argue further about it, as a +nervous headache disinclined her from debate. Mr. Cave was always +disinclined. The day passed disagreeably. Mr. Cave was, if anything, +more absent-minded than usual, and uncommonly irritable withal. In the +afternoon, when his wife was taking her customary sleep, he removed the +crystal from the window again. +</para> + +<para> + The next day Mr. Cave had to deliver a consignment of dog-fish at one +of the hospital schools, where they were needed for dissection. In his +absence Mrs. Cave's mind reverted to the topic of the crystal, and the +methods of expenditure suitable to a windfall of five pounds. She had +already devised some very agreeable expedients, among others a dress of +green silk for herself and a trip to Richmond, when a jangling of the +front door bell summoned her into the shop. The customer was an +examination coach who came to complain of the non-delivery of certain +frogs asked for the previous day. Mrs. Cave did not approve of this +particular branch of Mr. Cave's business, and the gentleman, who had +called in a somewhat aggressive mood, retired after a brief exchange of +words -- entirely civil so far as he was concerned. Mrs. Cave's eye then +naturally turned to the window; for the sight of the crystal was an +assurance of the five pounds and of her dreams. What was her surprise to +find it gone! +</para> + +<para> + She went to the place behind the locker on the counter, where she had +discovered it the day before. It was not there; and she immediately +began an eager search about the shop. +</para> + +<para> + When Mr. Cave returned from his business with the dog-fish, about a +quarter to two in the afternoon, he found the shop in some confusion, +and his wife, extremely exasperated and on her knees behind the counter, +routing among his taxidermic material. Her face came up hot and angry +over the counter, as the jangling bell announced his return, and she +forthwith accused him of "hiding it." +</para> + +<para> + "Hid what?" asked Mr. Cave. +</para> + +<para> + "The crystal!" +</para> + +<para> + At that Mr. Cave, apparently much surprised, rushed to the window. +"Isn't it here?" he said. "Great Heavens! what has become of it?" +</para> + +<para> + Just then, Mr. Cave's step-son re-entered the shop from the inner +room -- he had come home a minute or so before Mr. Cave -- and he was +blaspheming freely. He was apprenticed to a second-hand furniture dealer +down the road, but he had his meals at home, and he was naturally +annoyed to find no dinner ready. +</para> + +<para> + But, when he heard of the loss of the crystal, he forgot his meal, +and his anger was diverted from his mother to his step-father. Their +first idea, of course, was that he had hidden it. But Mr. Cave stoutly +denied all knowledge of its fate -- freely offering his bedabbled +affidavit in the matter -- and at last was worked up to the point of +accusing, first, his wife and then his step-son of having taken it with +a view to a private sale. So began an exceedingly acrimonious and +emotional discussion, which ended for Mrs. Cave in a peculiar nervous +condition midway between hysterics and amuck, and caused the step-son to +be half-an-hour late at the furniture establishment in the afternoon. +Mr. Cave took refuge from his wife's emotions in the shop. +</para> + +<para> + In the evening the matter was resumed, with less passion and in a +judicial spirit, under the presidency of the step-daughter. The supper +passed unhappily and culminated in a painful scene. Mr. Cave gave way at +last to extreme exasperation, and went out banging the front door +violently. The rest of the family, having discussed him with the freedom +his absence warranted, hunted the house from garret to cellar, hoping to +light upon the crystal. +</para> + +<para> + The next day the two customers called again. They were received by +Mrs. Cave almost in tears. It transpired that no one could imagine all +that she had stood from Cave at various times in her married pilgrimage. +. . . She also gave a garbled account of the disappearance. The +clergyman and the Oriental laughed silently at one another, and said it +was very extraordinary. As Mrs. Cave seemed disposed to give them the +complete history of her life they made to leave the shop. Thereupon Mrs. +Cave, still clinging to hope, asked for the clergyman's address, so +that, if she could get anything out of Cave, she might communicate it. +The address was duly given, but apparently was afterwards mislaid. Mrs. +Cave can remember nothing about it. +</para> + +<para> + In the evening of that day, the Caves seem to have exhausted their +emotions, and Mr. Cave, who had been out in the afternoon, supped in a +gloomy isolation that contrasted pleasantly with the impassioned +controversy of the previous days. For some time matters were very badly +strained in the Cave household, but neither crystal nor customer +reappeared. +</para> + +<para> + Now, without mincing the matter, we must admit that Mr. Cave was a +liar. He knew perfectly well where the crystal was. It was in the rooms +of Mr. Jacoby Wace, Assistant Demonstrator at St. Catherine's Hospital, +Westbourne Street. It stood on the sideboard partially covered by a +black velvet cloth, and beside a decanter of American whisky. It is from +Mr. Wace, indeed, that the particulars upon which this narrative is +based were derived. Cave had taken off the thing to the hospital hidden +in the dog-fish sack, and there had pressed the young investigator to +keep it for him. Mr. Wace was a little dubious at first. His +relationship to Cave was peculiar. He had a taste for singular +characters, and he had more than once invited the old man to smoke and +drink in his rooms, and to unfold his rather amusing views of life in +general and of his wife in particular. Mr. Wace had encountered Mrs. +Cave, too, on occasions when Mr. Cave was not at home to attend to him. +He knew the constant interference to which Cave was subjected, and +having weighed the story judicially, he decided to give the crystal a +refuge. Mr. Cave promised to explain the reasons for his remarkable +affection for the crystal more fully +on a later occasion, but he spoke distinctly of seeing visions therein. +He called on Mr. Wace the same evening. +</para> + +<para> + He told a complicated story. The crystal he said had come into his +possession with other oddments at the forced sale of another curiosity +dealer's effects, and not knowing what its value might be, he had +ticketed it at ten shillings. It had hung upon his hands at that price +for some months, and he was thinking of "reducing the figure," when he +made a singular discovery. +</para> + +<para> + At that time his health was very bad -- and it must be borne in mind +that, throughout all this experience, his physical condition was one of +ebb -- and he was in considerable distress by reason of the negligence, +the positive ill-treatment even, he received from his wife and +step-children. His wife was vain, extravagant, unfeeling and had a +growing taste for private drinking; his step-daughter was mean and +over-reaching; and his step-son had conceived a violent dislike for him, +and lost no chance of showing it. The requirements of his business +pressed heavily upon him, and Mr. Wace does not think that he was +altogether free from occasional intemperance. He had begun life in a +comfortable position, he was a man of fair education, and he suffered, +for weeks at a stretch, from melancholia and insomnia. Afraid to disturb +his family, he would slip quietly from his wife's side, when his +thoughts became intolerable, and wander about the house. And about three +o'clock one morning, late in August, chance directed him into the shop. +</para> + +<para> + The dirty little place was impenetrably black except in one spot, +where he perceived an unusual glow of light. Approaching this, he +discovered it to be the crystal egg, which was standing on the corner of +the counter towards the window. A thin ray smote through a crack in the +shutters, impinged upon the object, and seemed as it were to fill its +entire interior. +</para> + +<para> + It occurred to Mr. Cave that this was not in accordance with the laws +of optics as he had known them in his younger days. He could understand +the rays being refracted by the crystal and coming to a focus in its +interior, but this diffusion jarred with his physical conceptions. He +approached the crystal nearly, peering into it and round it, with a +transient revival of the scientific curiosity that in his youth had +determined his choice of a calling. He was surprised to find the light +not steady, but writhing within the substance of the egg, as though that +object was a hollow sphere of some luminous vapour. In moving about to +get different points of view, he suddenly found that he had come between +it and the ray, and that the crystal none the less remained luminous. +Greatly astonished, he lifted it out of the light ray and carried it to +the darkest part of the shop. It remained +bright for some four or five minutes, when it slowly faded and went out. +He placed it in the thin streak of daylight, and its luminousness was +almost immediately restored. +</para> + +<para> + So far, at least, Mr. Wace was able to verify the remarkable story of +Mr. Cave. He has himself repeatedly held this crystal in a ray of light +(which had to be of a less diameter than one millimetre). And in a +perfect darkness, such as could be produced by velvet wrapping, the +crystal did undoubtedly appear very faintly phosphorescent. It would +seem, however, that the luminousness was of some exceptional sort, and +not equally visible to all eyes; for Mr. Harbinger -- whose name will be +familiar to the scientific reader in connection with the Pasteur +Institute -- was quite unable to see any light whatever. And Mr. Wace's +own capacity for its appreciation was out of comparison inferior to that +of Mr. Cave's. Even with Mr. Cave the power varied very considerably: +his vision was most vivid during states of extreme weakness and fatigue. +</para> + +<para> + Now, from the outset this light in the crystal exercised a curious +fascination upon Mr. Cave. And it says more for his loneliness of soul +than a volume of pathetic writing could do, that he told no human being +of his curious observations. He seems to have been living in such an +atmosphere of petty spite that to admit the existence of a pleasure +would have been to risk the loss of it. He found that as the dawn +advanced, and the amount of diffused light increased, the crystal became +to all appearance non-luminous. And for some time he was unable to see +anything in it, except at night-time, in dark corners of the shop. +</para> + +<para> + But the use of an old velvet cloth, which he used as a background for +a collection of minerals, occurred to him, and by doubling this, and +putting it over his head and hands, he was able to get a sight of the +luminous movement within the crystal even in the day-time. He was very +cautious lest he should be thus discovered by his wife, and he practised +this occupation only in the afternoons, while she was asleep upstairs, +and then circumspectly in a hollow under the counter. And one day, +turning the crystal about in his hands, he saw something. It came and +went like a flash, but it gave him the impression that the object had +for a moment opened to him the view of a wide and spacious and strange +country; and, turning it about, he did, just as the light faded, see the +same vision again. +</para> + +<para> + Now, it would be tedious and unnecessary to state all the phases of +Mr. Cave's discovery from this point. Suffice that the effect was this: +the crystal, being peered into at an angle of about 137 degrees from the +direction of the illuminating ray, gave a clear and consistent picture +of a wide and peculiar country-side. It was not dream-like at +all: it produced a definite impression of reality, and the better the +light the more real and solid it seemed. It was a moving picture: that +is to say, certain objects moved in it, but slowly in an orderly manner +like real things, and, according as the direction of the lighting and +vision changed, the picture changed also. It must, indeed, have been +like looking through an oval glass at a view, and turning the glass +about to get at different aspects. +</para> + +<para> + Mr. Cave's statements, Mr. Wace assures me, were extremely +circumstantial, and entirely free from any of that emotional quality +that taints hallucinatory impressions. But it must be remembered that +all the efforts of Mr. Wace to see any similar clarity in the faint +opalescence of the crystal were wholly unsuccessful, try as he would. +The difference in intensity of the impressions received by the two men +was very great, and it is quite conceivable that what was a view to Mr. +Cave was a mere blurred nebulosity to Mr. Wace. +</para> + +<para> + The view, as Mr. Cave described it, was invariably of an extensive +plain, and he seemed always to be looking at it from a considerable +height, as if from a tower or a mast. To the east and to the west the +plain was bounded at a remote distance by vast reddish cliffs, which +reminded him of those he had seen in some picture; but what the picture +was Mr. Wace was unable to ascertain. These cliffs passed north and +south -- he could tell the points of the compass by the stars that were +visible of a night -- receding in an almost illimitable perspective and +fading into the mists of the distance before they met. He was nearer the +eastern set of cliffs, on the occasion of his first vision the sun was +rising over them, and black against the sunlight and pale against their +shadow appeared a multitude of soaring forms that Mr. Cave regarded as +birds. A vast range of buildings spread below him; he seemed to be +looking down upon them; and, as they approached the blurred and +refracted edge of the picture, they became indistinct. There were also +trees curious in shape, and in colouring, a deep mossy green and an +exquisite grey, beside a wide and shining canal. And something great and +brilliantly coloured flew across the picture. But the first time Mr. +Cave saw these pictures he saw only in flashes, his hands shook, his +head moved, the vision came and went, and grew foggy and indistinct. And +at first he had the greatest difficulty in finding the picture again +once the direction of it was lost. +</para> + +<para> + His next clear vision, which came about a week after the first, the +interval having yielded nothing but tantalising glimpses and some useful +experience, showed him the view down the length of the valley. The view +was different, but he had a curious persuasion, which his subsequent +observations abundantly confirmed, that he was regarding this strange +world from exactly the same spot, although he was looking +in a different direction. The long facade of the great building, whose +roof he had looked down upon before, was now receding in perspective. He +recognised the roof. In the front of the facade was a terrace of massive +proportions and extraordinary length, and down the middle of the +terrace, at certain intervals, stood huge but very graceful masts, +bearing small shiny objects which reflected the setting sun. The import +of these small objects did not occur to Mr. Cave until some time after, +as he was describing the scene to Mr. Wace. The terrace overhung a +thicket of the most luxuriant and graceful vegetation, and beyond this +was a wide grassy lawn on which certain broad creatures, in form like +beetles but enormously larger, reposed. Beyond this again was a richly +decorated causeway of pinkish stone; and beyond that, and lined with +dense red weeds, and passing up the valley exactly parallel with the +distant cliffs, was a broad and mirror-like expanse of water. The air +seemed full of squadrons of great birds, manoeuvring in stately curves; +and across the river was a multitude of splendid buildings, richly +coloured and glittering with metallic tracery and facets, among a forest +of moss-like and lichenous trees. And suddenly something flapped +repeatedly across the vision, like the fluttering of a jewelled fan or +the beating of a wing, and a face, or rather the upper part of a face +with very large eyes, came as it were close to his own and as if on the +other side of the crystal. Mr. Cave was so startled and so impressed by +the absolute reality of these eyes, that he drew his head back from the +crystal to look behind it. He had become so absorbed in watching that he +was quite surprised to find himself in the cool darkness of his little +shop, with its familiar odour of methyl, mustiness, and decay. And, as +he blinked about him, the glowing crystal faded, and went out. +</para> + +<para> + Such were the first general impressions of Mr. Cave. The story is +curiously direct and circumstantial. From the outset, when the valley +first flashed momentarily on his senses, his imagination was strangely +affected, and, as he began to appreciate the details of the scene he +saw, his wonder rose to the point of a passion. He went about his +business listless and distraught, thinking only of the time when he +should be able to return to his watching. And then a few weeks after his +first sight of the valley came the two customers, the stress and +excitement of their offer, and the narrow escape of the crystal from +sale, as I have already told. +</para> + +<para> + Now, while the thing was Mr. Cave's secret, it remained a mere +wonder, a thing to creep to covertly and peep at, as a child might peep +upon a forbidden garden. But Mr. Wace has, for a young scientific +investigator, a particularly lucid and consecutive habit of mind. +himself, by seeing the phosphorescence with his own eyes, that there +really was a certain evidence for Mr. Cave's statements, he proceeded to +develop the matter systematically. Mr. Cave was only too eager to come +and feast his eyes on this wonderland he saw, and he came every night +from half-past eight until half-past ten, and sometimes, in Mr. Wace's +absence, during the day. On Sunday afternoons, also, he came. From the +outset Mr. Wace made copious notes, and it was due to his scientific +method that the relation between the direction from which the initiating +ray entered the crystal and the orientation of the picture were proved. +And, by covering the crystal in a box perforated only with a small +aperture to admit the exciting ray, and by substituting black holland +for his buff blinds, he greatly improved the conditions of the +observations; so that in a little while they were able to survey the +valley in any direction they desired. +</para> + +<para> + So having cleared the way, we may give a brief account of this +visionary world within the crystal. The things were in all cases seen by +Mr. Cave, and the method of working was invariably for him to watch the +crystal and report what he saw, while Mr. Wace (who as a science student +had learnt the trick of writing in the dark) wrote a brief note of his +report. When the crystal faded, it was put into its box in the proper +position and the electric light turned on. Mr. Wace asked questions, and +suggested observations to clear up difficult points. Nothing, indeed, +could have been less visionary and more matter-of-fact. +</para> + +<para> + The attention of Mr. Cave had been speedily directed to the bird-like +creatures he had seen so abundantly present in each of his earlier +visions. His first impression was soon corrected, and he considered for +a time that they might represent a diurnal species of bat. Then he +thought, grotesquely enough, that they might be cherubs. Their heads +were round, and curiously human, and it was the eyes of one of them that +had so startled him on his second observation. They had broad, silvery +wings, not feathered, but glistening almost as brilliantly as new-killed +fish and with the same subtle play of colour, and these wings were not +built on the plan of a bird-wing or bat, Mr. Wace learned, but supported +by curved ribs radiating from the body. (A sort of butterfly wing with +curved ribs seems best to express their appearance.) The body was small, +but fitted with two bunches of prehensile organs, like long tentacles, +immediately under the mouth. Incredible as it appeared to Mr. Wace, the +persuasion at last became irresistible, that it was these creatures +which owned the great quasi-human buildings and the magnificent garden +that made the broad valley so splendid. And Mr. Cave perceived that the +buildings, with other peculiarities, had no doors, but that the great +circular windows, which +opened freely, gave the creatures egress and entrance. They would alight +upon their tentacles, fold their wings to a smallness almost rod-like, +and hop into the interior. But among them was a multitude of +smaller-winged creatures, like great dragon-flies and moths and flying +beetles, and across the greensward brilliantly-coloured gigantic +ground-beetles crawled lazily to and fro. Moreover, on the causeways and +terraces, large-headed creatures similar to the greater winged flies, +but wingless, were visible, hopping busily upon their hand-like tangle +of tentacles. +</para> + +<para> + Allusion has already been made to the glittering objects upon masts +that stood upon the terrace of the nearer building. It dawned upon Mr. +Cave, after regarding one of these masts very fixedly on one +particularly vivid day, that the glittering object there was a crystal +exactly like that into which he peered. And a still more careful +scrutiny convinced him that each one in a vista of nearly twenty carried +a similar object. +</para> + +<para> + Occasionally one of the large flying creatures would flutter up to +one, and, folding its wings and coiling a number of its tentacles about +the mast, would regard the crystal fixedly for a space, -- sometimes for +as long as fifteen minutes. And a series of observations, made at the +suggestion of Mr. Wace, convinced both watchers that, so far as this +visionary world was concerned, the crystal into which they peered +actually stood at the summit of the end-most mast on the terrace, and +that on one occasion at least one of these inhabitants of this other +world had looked into Mr. Cave's face while he was making these +observations. +</para> + +<para> + So much for the essential facts of this very singular story. Unless +we dismiss it all as the ingenious fabrication of Mr. Wace, we have to +believe one of two things: either that Mr. Cave's crystal was in two +worlds at once, and that, while it was carried about in one, it remained +stationary in the other, which seems altogether absurd; or else that it +had some peculiar relation of sympathy with another and exactly similar +crystal in this other world, so that what was seen in the interior of +the one in this world, was, under suitable conditions, visible to an +observer in the corresponding crystal in the other world; and vice +versa. At present, indeed, we do not know of any way in which two +crystals could so come en rapport, but nowadays we know enough to +understand that the thing is not altogether impossible. This view of the +crystals as en rapport was the supposition that occurred to Mr. Wace, +and to me at least it seems extremely plausible. . . . +</para> + +<para> + And where was this other world? On this, also, the alert intelligence +of Mr. Wace speedily threw light. After sunset, the sky darkened +rapidly -- there was a very brief twilight interval indeed -- and the +stars shone out. They were recognisably the same as those we see, +arranged in the same constellations. Mr. Cave recognised the Bear, the +Pleiades, Aldebaran, and Sirius: so that the other world must be +somewhere in the solar system, and, at the utmost, only a few hundreds +of millions of miles from our own. Following up this clue, Mr. Wace +learned that the midnight sky was a darker blue even than our midwinter +sky, and that the sun seemed a little smaller. And there were two small +moons! "like our moon but smaller, and quite differently marked" one of +which moved so rapidly that its motion was clearly visible as one +regarded it. These moons were never high in the sky, but vanished as +they rose: that is, every time they revolved they were eclipsed because +they were so near their primary planet. And all this answers quite +completely, although. Mr. Cave did not know it, to what must be the +condition of things on Mars. +</para> + +<para> + Indeed, it seems an exceedingly plausible conclusion that peering +into this crystal Mr. Cave did actually see the planet Mars and its +inhabitants. And, if that be the case, then the evening star that shone +so brilliantly in the sky of that distant vision, was neither more nor +less than our own familiar earth. +</para> + +<para> + For a time the Martians -- if they were Martians -- do not seem to +have known of Mr. Cave's inspection. Once or twice one would come to +peer, and go away very shortly to some other mast, as though the vision +was unsatisfactory. During this time Mr. Cave was able to watch the +proceedings of these winged people without being disturbed by their +attentions, and, although his report is necessarily vague and +fragmentary, it is nevertheless very suggestive. Imagine the impression +of humanity a Martian observer would get who, after a difficult process +of preparation and with considerable fatigue to the eyes, was able to +peer at London from the steeple of St. Martin's Church for stretches, at +longest, of four minutes at a time. Mr. Cave was unable to ascertain if +the winged Martians were the same as the Martians who hopped about the +causeways and terraces, and if the latter could put on wings at will. He +several times saw certain clumsy bipeds, dimly suggestive of apes, white +and partially translucent, feeding among certain of the lichenous trees, +and once some of these fled before one of the hopping, round-headed +Martians. The latter caught one in its tentacles, and then the picture +faded suddenly and left Mr. Cave most tantalisingly in the dark. On +another occasion a vast thing, that Mr. Cave thought at first was some +gigantic insect, appeared advancing along the causeway beside the canal +with extraordinary rapidity. As this drew nearer Mr. Cave perceived that +it was a mechanism of shining +metals and of extraordinary complexity. And then, when he looked again, +it had passed out of sight. +</para> + +<para> + After a time Mr. Wace aspired to attract the attention of the +Martians, and the next time that the strange eyes of one of them +appeared close to the crystal Mr. Cave cried out and sprang away, and +they immediately turned on the light and began to gesticulate in a +manner suggestive of signalling. But when at last Mr. Cave examined the +crystal again the Martian had departed. +</para> + +<para> + Thus far these observations had progressed in early November, and +then Mr. Cave, feeling that the suspicions of his family about the +crystal were allayed, began to take it to and fro with him in order +that, as occasion arose in the daytime or night, he might comfort +himself with what was fast becoming the most real thing in his existence. +</para> + +<para> + In December Mr. Wace's work in connection with a forthcoming +examination became heavy, the sittings were reluctantly suspended for a +week, and for ten or eleven days -- he is not quite sure which -- he saw +nothing of Cave. He then grew anxious to resume these investigations, +and, the stress of his seasonal labours being abated, he went down to +Seven Dials. At the corner he noticed a shutter before a bird fancier's +window, and then another at a cobbler's. Mr. Cave's shop was closed. +</para> + +<para> + He rapped and the door was opened by the step-son in black. He at +once called Mrs. Cave, who was, Mr. Wace could not but observe, in cheap +but ample widow's weeds of the most imposing pattern. Without any very +great surprise Mr. Wace learnt that Cave was dead and already buried. +She was in tears, and her voice was a little thick. She had just +returned from Highgate. Her mind seemed occupied with her own prospects +and the honourable details of the obsequies, but Mr. Wace was at last +able to learn the particulars of Cave's death. He had been found dead in +his shop in the early morning, the day after his last visit to Mr. Wace, +and the crystal had been clasped in his stone-cold hands. His face was +smiling, said Mrs. Cave, and the velvet cloth from the minerals lay on +the floor at his feet. He must have been dead five or six hours when he +was found. +</para> + +<para> + This came as a great shock to Wace, and he began to reproach ho,self +bitterly for having neglected the plain symptoms of the old man's +ill-health. But his chief thought was of the crystal. He approached that +topic in a gingerly manner, because he knew Mrs. Cave's peculiarities. +He was dumbfoundered to learn that it was sold. +</para> + +<para> + Mrs. Cave's first impulse, directly Cave's body had been taken +upstairs, had been to write to the mad clergyman who had offered five +pounds for the crystal, informing him of its recovery; but after a +violent hunt in which her daughter joined her, they were convinced +</para> + +<para> +of the loss of his address. As they were without the means required to +mourn and bury Cave in the elaborate style the dignity of an old Seven +Dials inhabitant demands, they had appealed to a friendly +fellow-tradesman in Great Portland Street. He had very kindly taken over +a portion of the stock at a valuation. The valuation was his own and the +crystal egg was included in one of the lots. Mr. Wace, after a few +suitable consolatory observations, a little offhandedly proffered +perhaps, hurried at once to Great Portland Street. But there he learned +that the crystal egg had already been sold to a tall, dark man in grey. +And there the material facts in this curious, and to me at least very +suggestive, story come abruptly to an end. The Great Portland Street +dealer did not know who the tall dark man in grey was, nor had he +observed him with sufficient attention to describe him minutely. He did +not even know which way this person had gone after leaving the shop. For +a time Mr. Wace remained in the shop, trying the dealer's patience with +hopeless questions, venting his own exasperation. And at last, realising +abruptly that the whole thing had passed out of his hands, had vanished +like a vision of the night, he returned to his own rooms, a little +astonished to find the notes he had made still tangible and visible upon +his untidy table. +</para> + +<para> + His annoyance and disappointment were naturally very great. He made a +second call (equally ineffectual) upon the Great Portland Street dealer, +and he resorted to advertisements in such periodicals as were likely to +come into the hands of a bric-a-brac collector. He also wrote letters to +The Daily Chronicle and Nature, but both those periodicals, suspecting a +hoax, asked him to reconsider his action before they printed, and he was +advised that such a strange story, unfortunately so bare of supporting +evidence, might imperil his reputation as an investigator. Moreover, the +calls of his proper work were urgent. So that after a month or so, save +for an occasional reminder to certain dealers, he had reluctantly to +abandon the quest for the crystal egg, and from that day to this it +remains undiscovered. Occasionally, however, he tells me, and I can +quite believe him, he has bursts of zeal, in which he abandons his more +urgent occupation and resumes the search. +</para> + +<para> + Whether or not it will remain lost for ever, with the material and +origin of it, are things equally speculative at the present time. If the +present purchaser is a collector, one would have expected the enquiries +of Mr. Wace to have readied him through the dealers. He has been able to +discover Mr. Cave's clergyman and "Oriental" -- no other than the Rev. +James Parker and the young Prince of Bosso-Kuni in Java. I am obliged to +them for certain particulars. The object of the Prince was simply +curiosity -- and extravagance. He was so eager to buy, +because Cave was so oddly reluctant to sell. It is just as possible that +the buyer in the second instance was simply a casual purchaser and not a +collector at all, and the crystal egg, for all I know, may at the +present moment be within a mile of me, decorating a drawing-room or +serving as a paper-weight -- its remarkable functions all unknown. +Indeed, it is partly with the idea of such a possibility that I have +thrown this narrative into a form that will give it a chance of being +read by the ordinary consumer of fiction. +</para> + +<para> + My own ideas in the matter are practically identical with those of +Mr. Wace. I believe the crystal on the mast in Mars and the crystal egg +of Mr. Cave's to be in some physical, but at present quite inexplicable, +way en rapport, and we both believe further that the terrestrial crystal +must have been -- possibly at some remote date -- sent hither from that +planet, in order to give the Martians a near view of our affairs. +Possibly the fellows to the crystals in the other masts are also on our +globe. No theory of hallucination suffices for the facts. +</para> + +</chapter> + +</book> + diff --git a/src/io/doc2html.xsl b/src/io/doc2html.xsl new file mode 100644 index 000000000..f8734a1c2 --- /dev/null +++ b/src/io/doc2html.xsl @@ -0,0 +1,63 @@ +<?xml version='1.0'?> +<xsl:stylesheet + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'> +<xsl:output method="html"/> + +<xsl:template match="book"> + <html> + <head> + <style TYPE="text/css"> + p + { + text-indent: 0.25in + } + h3 + { + font-family: Arial, Helvetica, 'Bitstream Vera Sans', 'Luxi Sans', Verdana, Sans-Serif; + font-size: 24px; + } + h4 + { + font-family: Arial, Helvetica, 'Bitstream Vera Sans', 'Luxi Sans', Verdana, Sans-Serif; + font-size: 16px; + } + + </style> + </head> + <body> + <xsl:apply-templates/> + </body> + </html> +</xsl:template> + +<xsl:template match="bookinfo"> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="title"> + <h3> + <xsl:apply-templates/> + </h3> +</xsl:template> + +<xsl:template match="author"> + <h4> + <xsl:value-of select="./firstname"/> + <xsl:text> </xsl:text> + <xsl:value-of select="./surname"/> + </h4> +</xsl:template> + + +<xsl:template match="chapter"> + <hr/> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="para"> + <p> + <xsl:apply-templates/> + </p> +</xsl:template> + +</xsl:stylesheet> diff --git a/src/io/ftos.cpp b/src/io/ftos.cpp new file mode 100644 index 000000000..47f0dc232 --- /dev/null +++ b/src/io/ftos.cpp @@ -0,0 +1,482 @@ +/* ////////////////////////////////////////////////////////////////////// +// ftos.cc +// +// Copyright (c) 1996-2003 Bryce W. Harrington [bryce at osdl dot org] +// +//----------------------------------------------------------------------- +// License: This code may be used by anyone for any purpose +// so long as the copyright notices and this license +// statement remains attached. +//----------------------------------------------------------------------- +// +// string ftos(double val[, char mode[, int sigfig[, int precision[, int options]]]]) +// +// DESCRIPTION +// This routine is intended to replace the typical use of sprintf for +// converting floating point numbers into strings. +// +// To one-up sprintf, an additional mode was created - 'h' mode - +// which produces numbers in 'engineering notation' - exponents are +// always shown in multiples of 3. To non-engineers this mode is +// probably irrelevant, but for engineers (and scientists) it is SOP. +// +// One other new feature is an option to use 'x10^' instead of the +// conventional 'E' for exponental notation. This is entirely for +// aesthetics since numbers in the 'x10^' form cannot be used as +// inputs for most programs. +// +// For most cases, the routine can simply be used with the defaults +// and acceptable results will be produced. No fill zeros or trailing +// zeros are shown, and exponential notation is only used for numbers +// greater than 1e6 or less than 1e-3. +// +// The one area where sprintf may surpass this routine is in width control. +// No provisions are made in this routine to restrict a number to a +// certain number of digits (thus allowing the number to be constrained +// to an 8 space column, for instance.) Along with this, it does not +// support pre-padding a number with zeros (e.g., '5' -> '0005') and will +// not post-pad a number with spaces (i.e., allow left-justification.) +// +// If width control is this important, then the user will probably want to +// use the stdio routines, which really is well suited for outputting +// columns of data with a brief amount of code. +// +// PARAMETERS +// val - number to be converted +// mode - can be one of four possible values. Default is 'g' +// +// e: Produces numbers in scientific notation. One digit +// is shown on the left side of the decimal, the rest +// on the right, and the exponential is always shown. +// EXAMPLE: 1.04e-4 +// +// f: Produces numbers with fixed format. Number is shown +// exact, with no exponent. +// EXAMPLE: 0.000104 +// +// g: If val is greater than 1e6 or less than 1e-3 it will +// be shown in 'e' format, otherwise 'f' format will be +// used. +// +// h: Produces numbers in engineering format. Result is +// identical to 'f' format for numbers between 1 and +// 1e3, otherwise, the number is shown such that it +// always begins with a nonzero digit on the left side +// (unless number equals zero), and the exponential is +// a multiple of 3. +// EXAMPLE: 104e-6 +// +// If the mode is expressed as a capital letter (e.g., 'F') +// then the exponential part of the number will also be +// capitalized (e.g., '1E6' or '1X10^6'.) +// +// sigfig - the number of significant figures. These are the digits +// that are "retained". For example, the following numbers +// all have four sigfigs: +// 1234 12.34 0.0001234 1.234e-10 +// the last digit shown will be rounded in the standard +// manner (down if the next digit is less than 5, up otherwise.) +// +// precision - the number of digits to show to the right of the decimal. +// For example, all of the following numbers have precisions +// of 2: +// 1234.00 12.34 0.00 1.23e-10 123.40e-12 +// +// options - several options are allowed to control the look of the +// output. +// +// FORCE_DECIMAL - require the decimal point to be shown for +// numbers that do not have any fractional digits (or that +// have a precision set to zero) +// EXAMPLE: 1.e6 +// FORCE_EXP_ZERO - pad the 10's zero in exponent if necessary +// EXAMPLE: 1e06 +// FORCE_HUNDRED_EXP_ZERO - pad the 100's zero in exponent if +// necessary. Also pads 10's zero in exponent if necessary. +// EXAMPLE: 1e006 +// FORCE_EXP_PLUS - show the '+' in the exponent if exponent +// is used. +// EXAMPLE: 1e+6 +// FORCE_EXP - force the output to display the exponent +// EXAMPLE: 0e0 +// FORCE_X10 - use x10^ instead of E +// EXAMPLE: 1x10^6 +// FORCE_PLUS - force output of the '+' for positive numbers +// EXAMPLE: +1e6 +// +// Options can be combined using the usual OR method. For +// example, +// +// ftos(123.456, 'f', -1, -1, FORCE_PLUS | FORCE_X10 | FORCE_EXP) +// +// gives "+123.456x10^0" +// +// RETURN VALUE +// The string representation of the number is returned from the routine. +// The ANSI C++ Standard "string" class was used for several important +// reasons. First, because the string class manages it's own space, the +// ftos routine does not need to concern itself with writing to unallocated +// areas of memory or with handling memory reallocation internally. Second, +// it allows return of an object, not a pointer to an object; this may not +// be as efficient, but it is cleaner and safer than the alternative. Third, +// the routine's return value can be directly assigned to a variable, i.e. +// string var = ftos(3.1415); +// which makes code much easier to comprehend and modify. +// +// Internally, the ftos routine uses fairly typical string operators (=, +=, +// +, etc.) which pretty much any other flavor of string class will define as +// well. Thus if one does not have access to the ANSI C++ Standard string +// class, the user can substitute another with little difficulty. (If the +// alternate class is not named "string" then redefine "string" to whatever +// you wish to use. For example, +// #define string CString +// +// November 1996 - Bryce Harrington +// Created ftoa and ftos +// +// December 1996 - Bryce Harrington +// Added engineering notation mode, added sigfig capability, added +// significant debug code, added options, thoroughly debugged and +// tested the code. +// +// +// June 1999 - Bryce Harrington +// Modified to run on Linux for WorldForge +// +// March 2003 - Bryce Harrington +// Removed DTAG() macros - use of fprintf(stderr,...) instead +// Broke out round/itos/ftos into separate files +// Removed curses bits +// +/////////////////////////////////////////////////////////////////////// */ + + +// This is the routine used for converting a floating point into a string +// This may be included in stdlib.h on some systems and may conflict. +// Let me know your system & etc. so I can properly #ifdef this, but +// try commenting the following four lines out if you run into conflicts. +// extern "C" { +// char* +// ecvt (double val, size_t ndigit, int *decpt, int *sign); +// } + +using namespace std; + +#ifndef HAS_ECVT +#include <glib.h> +#endif + + +#include "ftos.h" + + +// This routine counts from the end of a string like '10229000' to find the index +// of the first non-'0' character (5 would be returned for the above number.) +int countDigs(char *p) +{ + int length =0; + while (*(p+length)!='\0') length++; // Count total length + while (length>0 && *(p+length-1)=='0') length--; // Scan backwards for a non-'0' + return length; +} + +// This routine determines how many digits make up the left hand +// side of the number if the abs value of the number is greater than 1, or the +// digits that make up the right hand side if the abs value of the number +// is between 0 and 1. Returns 1 if v==0. Return value is positive for numbers +// greater than or equal to 1, negative for numbers less than 0.1, and zero for +// numbers between 0.1 and 1. +int countLhsDigits(double v) +{ + if (v<0) v = -v; // Take abs value + else if (v==0) return 1; // Special case if v==0 + + int n=0; + for (; v<0.1; v*=10) // Count digits on right hand side (l.t. 0.1) + { n--; } + for (; v>=1; v/=10) // Count digits on left hand side (g.e. 1.0) + { n++; } + return n; +} + +// This is the routine that does the work of converting the number into a string. +string ftos(double val, char mode, int sigfig, int precision, int options) +{ + // Parse the options to a more usable form + // These options allow the user to control some of the ornaments on the + // number that is output. By default they are all false. Turning them + // on helps to "fix" the format of the number so it lines up in columns + // better. + // - require the decimal point to be shown for numbers that do not have + // any fractional digits (or that have a precision set to zero + bool forceDecimal = (options & FORCE_DECIMAL); + // - show the 10's and 100's zero in exponent + bool forceExpZero = (options & FORCE_EXP_ZERO); + bool forceHundredExpZero = (options & FORCE_HUNDRED_EXP_ZERO); + // - show the '+' in the exponent if exponent is used + bool forceExpPlus = (options & FORCE_EXP_PLUS); + // - force the output to display the exponent + bool forceExponent = (options & FORCE_EXP); + // - use x10^ instead of E + bool forcex10 = (options & FORCE_X10); + // - force output of the '+' for positive numbers + bool forcePlus = (options & FORCE_PLUS); + +#ifdef DEBUG + fprintf(stderr, "Options: "); + fprintf(stderr, " %4s = %s ", "x10", (forcex10 ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", ".", (forceDecimal ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e0", (forceExpZero ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e00", (forceHundredExpZero ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e+", (forceExpPlus ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e", (forceExponent ? "on" : "off" )); + fprintf(stderr, " %4s = %s \n", "+#", (forcePlus ? "on" : "off" )); +#endif + + // - exponent usage + bool useExponent = false; + + // Determine the case for the 'e' (if used) + char E = (forcex10)? 'x' : 'e'; + if (g_ascii_isupper(mode)) { + E = g_ascii_toupper(E); + mode = g_ascii_tolower(mode); + } + + // Determine how many decimals we're interested in + int L = countLhsDigits(val); + +#ifdef DEBUG + fprintf(stderr, "*** L is %s\n", itos(L).c_str()); +#endif + + int count = 0; + if (sigfig==0) // bad input - don't want any sigfigs??!! + return ""; + else if (precision>=0) { // Use fixed number of decimal places + count = precision; + if (mode == 'e') count += 1; + else if (mode == 'f') count += L; + else if (mode == 'g') count += (L>6 || L<-3)? 1 : L; + else if (mode == 'h') count += (L>0)? ((L-1)%3+1) : (L%3+3); + if (sigfig>0) count = (sigfig > count)? count : sigfig; // Use sigfig # if it means more decimal places + } + else if (sigfig>0) // Just use sigfigs + count = sigfig; + else // prec < 0 and sigfig < 0 + count = 10; +#ifdef DEBUG + fprintf(stderr, "*** count is %s\n", itos(count).c_str()); +#endif + + // Get number's string rep, sign, and exponent + int sign = 0; + int decimal=0; + +#ifdef HAS_ECVT + char *p = ecvt(val, count, &decimal, &sign); +#else + char *p = (char *) g_strdup_printf("%.0f", val); + // asprintf(&p, "%.0f", val); +#endif + +#ifdef DEBUG + fprintf(stderr, "*** string rep is %s\n", p); + fprintf(stderr, "*** decimal is %s\n", itos(decimal).c_str()); + fprintf(stderr, "*** sign is %s\n", itos(sign).c_str()); +#endif + + // Count the number of relevant digits in the resultant number + int dig = countDigs(p); + if (dig < sigfig) dig = sigfig; + +#ifdef DEBUG + fprintf(stderr, "*** digs is %s\n", itos(dig).c_str()); +#endif + + // Determine number of digits to put on left side of the decimal point + int lhs=0; + // For 'g' mode, decide whether to use 'e' or 'f' format. + if (mode=='g') mode = (decimal>6 || decimal<-3)? 'e' : 'f'; + switch (mode) { + case 'e': + lhs = 1; // only need one char on left side + useExponent = true; // force exponent use + break; + + case 'f': + lhs = (decimal<1)? 1 : decimal; + // use one char on left for num < 1, + // otherwise, use the number of decimal places. + useExponent = false; // don't want exponent for 'f' format + break; + + case 'h': + if (val==0.0) // special case for if value is zero exactly. + lhs = 0; // this prevents code from returning '000.0' + else + lhs = (decimal<=0)? (decimal)%3 + 3 : (decimal-1)%3+1; + useExponent = !(lhs==decimal); // only use exponent if we really need it + break; + + default: + return "**bad mode**"; + } + +#ifdef DEBUG + fprintf(stderr, "*** lhs is %s\n", itos(lhs).c_str()); +#endif + + // Figure out the number of digits to show in the right hand side + int rhs=0; + if (precision>=0) + rhs = precision; + else if (val == 0.0) + rhs = 0; + else if (useExponent || decimal>0) + rhs = dig-lhs; + else + rhs = dig-decimal; + + // can't use a negative rhs value, so turn it to zero if that is the case + if (rhs<0) rhs = 0; + +#ifdef DEBUG + fprintf(stderr, "*** rhs is", itos(rhs).c_str()); +#endif + + // Determine the exponent + int exponent = decimal - lhs; + if (val==0.0) exponent=0; // prevent zero from getting an exponent +#ifdef DEBUG + fprintf(stderr, "*** exponent is %s\n", itos(exponent).c_str()); +#endif + + string ascii; + + // output the sign + if (sign) ascii += "-"; + else if (forcePlus) ascii += "+"; + + // output the left hand side + if (!useExponent && decimal<=0) // if fraction, put the 0 out front + ascii += '0'; + else // is either exponential or >= 1, so write the lhs + for (; lhs>0; lhs--) + ascii += (*p)? *p++ : int('0'); // now fill in the numbers before decimal + +#ifdef DEBUG + fprintf(stderr, "*** ascii + sign + lhs is %s\n", ascii.c_str()); +#endif + + // output the decimal point + if (forceDecimal || rhs>0) + ascii += '.'; + + // output the right hand side + if (!useExponent && rhs>0) // first fill in zeros after dp and before numbers + while (decimal++ <0 && rhs-->0) + ascii += '0'; + for (; rhs>0 ; rhs--) // now fill in the numbers after decimal + ascii += (*p)? *p++ : int('0'); + +#ifdef DEBUG + fprintf(stderr, "*** ascii + . + rhs is %s\n", ascii.c_str()); +#endif + + if (forceExponent || useExponent) // output the entire exponent if required + { + ascii += E; // output the E or X + if (forcex10) ascii += "10^"; // if using 'x10^' format, output the '10^' part + + // output the exponent's sign + if (exponent < 0) { // Negative exponent + exponent = -exponent; // make exponent positive if needed + ascii += '-'; // output negative sign + } + else if (forceExpPlus) // We only want the '+' if it is asked for explicitly + ascii += '+'; + + // output the exponent + if (forceHundredExpZero || exponent >= 100) + ascii += ( (exponent/100) % 10 + '0' ); + if (forceHundredExpZero || forceExpZero || exponent >= 10) + ascii += ( (exponent/10) % 10 + '0' ); + ascii += ( exponent % 10 + '0' ); + +#ifdef DEBUG + fprintf(stderr, "*** ascii + exp is %s\n", ascii.c_str()); +#endif + } + +#ifdef DEBUG + fprintf(stderr, "*** End of ftos with ascii = ", ascii.c_str()); +#endif + /* finally, we can return */ + return ascii; +} + +#ifdef TESTFTOS + +int main() +{ + cout << "Normal (g): " << endl; + cout << "1.0 = " << ftos(1.0) << endl; + cout << "42 = " << ftos(42) << endl; + cout << "3.141 = " << ftos(3.141) << endl; + cout << "0.01 = " << ftos(0.01) << endl; + cout << "1.0e7 = " << ftos(1.0e7) << endl; + cout << endl; + + cout << "Scientific (e): " << endl; + cout << "1.0 = " << ftos(1.0, 'e') << endl; + cout << "42 = " << ftos(42, 'e') << endl; + cout << "3.141 = " << ftos(3.141, 'e') << endl; + cout << "0.01 = " << ftos(0.01, 'e') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'e') << endl; + cout << endl; + + cout << "Fixed (f): " << endl; + cout << "1.0 = " << ftos(1.0, 'f') << endl; + cout << "42 = " << ftos(42, 'f') << endl; + cout << "3.141 = " << ftos(3.141, 'f') << endl; + cout << "0.01 = " << ftos(0.01, 'f') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'f') << endl; + cout << endl; + + cout << "Engineering (h): " << endl; + cout << "1.0 = " << ftos(1.0, 'h') << endl; + cout << "42 = " << ftos(42, 'h') << endl; + cout << "3.141 = " << ftos(3.141, 'h') << endl; + cout << "0.01 = " << ftos(0.01, 'h') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'h') << endl; + cout << endl; + + cout << "Sigfigs: " << endl; + cout << "2 sf = " << ftos(1234, 'g', 2) << " " + << ftos(12.34, 'g', 2) << " " + << ftos(0, 'g', 2) << " " + << ftos(123.4e-11, 'g', 2) << endl; + cout << "4 sf = " << ftos(1234, 'g', 4) << " " + << ftos(12.34, 'g', 4) << " " + << ftos(0, 'g', 4) << " " + << ftos(123.4e-11, 'g', 4) << endl; + cout << "8 sf = " << ftos(1234, 'g', 8) << " " + << ftos(12.34, 'g', 8) << " " + << ftos(0, 'g', 8) << " " + << ftos(123.4e-11, 'g', 8) << endl; + cout << endl; + + cout << "x10 mode: " << endl; + cout << "1234 = " << ftos(1234, 'e', 4, -1, FORCE_X10 | FORCE_EXP) << endl; + cout << "1.01e10 = " << ftos(1.01e10, 'h', -1, -1, FORCE_X10 | FORCE_EXP) << endl; + cout << endl; + + cout << "itos tests..." << endl; + cout << "42 = " << itos(42) << endl; + cout << endl; + + return 0; +} + +#endif // TESTFTOS diff --git a/src/io/ftos.h b/src/io/ftos.h new file mode 100644 index 000000000..888def639 --- /dev/null +++ b/src/io/ftos.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////// +// ftos.h +// +// Copyright (c) 1996 Bryce W. Harrington - bryce@neptune.net +// +//----------------------------------------------------------------------- +// License: This code may be used by anyone for any purpose +// so long as the copyright notices and this license +// statement remains attached. +//----------------------------------------------------------------------- +// Description of file contents +// 1993 - Bryce Harrington +// Created initial ftoa routine +// +// October 1996 - Bryce Harrington +// Created itos from code taken from Kernighan & Ritchie +// _The C Programming Language_ 2nd edition +// +// November 1996 - Bryce Harrington +// Created new ftoa and ftos +// +// July 1999 - Bryce Harrington +// Ported to Linux for use in WorldForge +// +// January 2000 - Karsten Laux klaux@rhrk.uni-kl.de +// added ultos - convering ulong to string +// +///////////////////////////////////////////////////////////////////////// +#ifndef ftos_h +#define ftos_h + +#include <string> + +// ftos routine +const int FORCE_X10 = (1 << 0); +const int FORCE_DECIMAL = (1 << 1); +const int FORCE_EXP_ZERO = (1 << 2); +const int FORCE_HUNDRED_EXP_ZERO = (1 << 3); +const int FORCE_EXP_PLUS = (1 << 4); +const int FORCE_EXP = (1 << 5); +const int FORCE_PLUS = (1 << 6); + +/// +std::string ftos(double val, char mode='g', int sigfig=-1, int precision=-1, int options=0); +/// +std::string itos(int n); +/// +std::string ultos(unsigned long n); +/// +double rround(double x); // use rounding rule -> x to nearest int. +/// +double rround(double x, int k); // round to the kth place + +#endif // ftos_h diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp new file mode 100644 index 000000000..02309ecdd --- /dev/null +++ b/src/io/gzipstream.cpp @@ -0,0 +1,458 @@ +/** + * Zlib-enabled input and output streams + * + * This is a thin wrapper of libz calls, in order + * to provide a simple interface to our developers + * for gzip input and output. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "gzipstream.h" + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +#define OUT_SIZE 4000 + +/** + * + */ +GzipInputStream::GzipInputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream), + loaded(false), + totalIn(0), + totalOut(0), + outputBuf(NULL), + crc(0), + srcCrc(0), + srcSiz(0), + srcConsumed(0), + srcLen(0), + outputBufPos(0), + outputBufLen(0) +{ + memset( &d_stream, 0, sizeof(d_stream) ); +} + +/** + * + */ +GzipInputStream::~GzipInputStream() +{ + close(); + if ( srcBuf ) { + free(srcBuf); + srcBuf = 0; + } + if ( outputBuf ) { + free(outputBuf); + outputBuf = 0; + } +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int GzipInputStream::available() +{ + if (closed || !outputBuf) + return 0; + return outputBufLen - outputBufPos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void GzipInputStream::close() +{ + if (closed) + return; + + int zerr = inflateEnd(&d_stream); + if (zerr != Z_OK) { + printf("inflateEnd: Some kind of problem: %d\n", zerr); + } + + if ( srcBuf ) { + free(srcBuf); + srcBuf = 0; + } + if ( outputBuf ) { + free(outputBuf); + outputBuf = 0; + } + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int GzipInputStream::get() +{ + int ch = -1; + if (closed) { + // leave return value -1 + } + else if (!loaded && !load()) { + closed=true; + } else { + loaded = true; + + int zerr = Z_OK; + if ( outputBufPos >= outputBufLen ) { + // time to read more, if we can + zerr = fetchMore(); + } + + if ( outputBufPos < outputBufLen ) { + ch = (int)outputBuf[outputBufPos++]; + } + } + + return ch; +} + +#define FTEXT 0x01 +#define FHCRC 0x02 +#define FEXTRA 0x04 +#define FNAME 0x08 +#define FCOMMENT 0x10 + +bool GzipInputStream::load() +{ + crc = crc32(0L, Z_NULL, 0); + + std::vector<Byte> inputBuf; + while (true) + { + int ch = source.get(); + if (ch<0) + break; + inputBuf.push_back((Byte)(ch & 0xff)); + } + long inputBufLen = inputBuf.size(); + + if (inputBufLen < 19) //header + tail + 1 + { + return false; + } + + srcLen = inputBuf.size(); + srcBuf = (Bytef *)malloc(srcLen * sizeof(Byte)); + if (!srcBuf) { + return false; + } + + outputBuf = (unsigned char *)malloc(OUT_SIZE); + if ( !outputBuf ) { + free(srcBuf); + srcBuf = 0; + return false; + } + outputBufLen = 0; // Not filled in yet + + std::vector<unsigned char>::iterator iter; + Bytef *p = srcBuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; iter++) + *p++ = *iter; + + int headerLen = 10; + + //Magic + int val = (int)srcBuf[0]; + //printf("val:%x\n", val); + val = (int)srcBuf[1]; + //printf("val:%x\n", val); + + //Method + val = (int)srcBuf[2]; + //printf("val:%x\n", val); + + //flags + int flags = (int)srcBuf[3]; + + //time + val = (int)srcBuf[4]; + val = (int)srcBuf[5]; + val = (int)srcBuf[6]; + val = (int)srcBuf[7]; + + //xflags + val = (int)srcBuf[8]; + //OS + val = (int)srcBuf[9]; + + int cur = 10; +// if ( flags & FEXTRA ) { +// headerLen += 2; +// int xlen = +// TODO deal with optional header parts +// } + if ( flags & FNAME ) { + while ( srcBuf[cur] ) + { + cur++; + headerLen++; + } + headerLen++; + } + + + srcCrc = ((0x0ff & srcBuf[srcLen - 5]) << 24) + | ((0x0ff & srcBuf[srcLen - 6]) << 16) + | ((0x0ff & srcBuf[srcLen - 7]) << 8) + | ((0x0ff & srcBuf[srcLen - 8]) << 0); + //printf("srcCrc:%lx\n", srcCrc); + + srcSiz = ((0x0ff & srcBuf[srcLen - 1]) << 24) + | ((0x0ff & srcBuf[srcLen - 2]) << 16) + | ((0x0ff & srcBuf[srcLen - 3]) << 8) + | ((0x0ff & srcBuf[srcLen - 4]) << 0); + //printf("srcSiz:%lx/%ld\n", srcSiz, srcSiz); + + if ( srcSiz <= 0 ) { + return false; + } + + //outputBufLen = srcSiz + srcSiz/100 + 14; + + unsigned char *data = srcBuf + headerLen; + unsigned long dataLen = srcLen - (headerLen + 8); + //printf("%x %x\n", data[0], data[dataLen-1]); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + d_stream.next_in = data; + d_stream.avail_in = dataLen; + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + + int zerr = inflateInit2(&d_stream, -MAX_WBITS); + if ( zerr == Z_OK ) + { + zerr = fetchMore(); + } else { + printf("inflateInit2: Some kind of problem: %d\n", zerr); + } + + + return (zerr == Z_OK) || (zerr == Z_STREAM_END); +} + + +int GzipInputStream::fetchMore() +{ + int zerr = Z_OK; + + // TODO assumes we aren't called till the buffer is empty + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + outputBufLen = 0; + outputBufPos = 0; + + zerr = inflate( &d_stream, Z_SYNC_FLUSH ); + if ( zerr == Z_OK || zerr == Z_STREAM_END ) { + outputBufLen = OUT_SIZE - d_stream.avail_out; + if ( outputBufLen ) { + crc = crc32(crc, (const Bytef *)outputBuf, outputBufLen); + } + //printf("crc:%lx\n", crc); +// } else if ( zerr != Z_STREAM_END ) { +// // TODO check to be sure this won't happen for partial end reads +// printf("inflate: Some kind of problem: %d\n", zerr); + } + + return zerr; +} + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +GzipOutputStream::GzipOutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + + totalIn = 0; + totalOut = 0; + crc = crc32(0L, Z_NULL, 0); + + //Gzip header + destination.put(0x1f); + destination.put(0x8b); + + //Say it is compressed + destination.put(Z_DEFLATED); + + //flags + destination.put(0); + + //time + destination.put(0); + destination.put(0); + destination.put(0); + destination.put(0); + + //xflags + destination.put(0); + + //OS code - from zutil.h + //destination.put(OS_CODE); + //apparently, we should not explicitly include zutil.h + destination.put(0); + +} + +/** + * + */ +GzipOutputStream::~GzipOutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void GzipOutputStream::close() +{ + if (closed) + return; + + flush(); + + //# Send the CRC + uLong outlong = crc; + for (int n = 0; n < 4; n++) + { + destination.put((int)(outlong & 0xff)); + outlong >>= 8; + } + //# send the file length + outlong = totalIn & 0xffffffffL; + for (int n = 0; n < 4; n++) + { + destination.put((int)(outlong & 0xff)); + outlong >>= 8; + } + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void GzipOutputStream::flush() +{ + if (closed || inputBuf.size()<1) + return; + + uLong srclen = inputBuf.size(); + Bytef *srcbuf = (Bytef *)malloc(srclen * sizeof(Byte)); + if (!srcbuf) + { + return; + } + + uLong destlen = srclen; + Bytef *destbuf = (Bytef *)malloc((destlen + (srclen/100) + 13) * sizeof(Byte)); + if (!destbuf) + { + free(srcbuf); + return; + } + + std::vector<unsigned char>::iterator iter; + Bytef *p = srcbuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; iter++) + *p++ = *iter; + + crc = crc32(crc, (const Bytef *)srcbuf, srclen); + + int zerr = compress(destbuf, (uLongf *)&destlen, srcbuf, srclen); + if (zerr != Z_OK) + { + printf("Some kind of problem\n"); + } + + totalOut += destlen; + //skip the redundant zlib header and checksum + for (uLong i=2; i<destlen-4 ; i++) + { + destination.put((int)destbuf[i]); + } + + destination.flush(); + + inputBuf.clear(); + free(srcbuf); + free(destbuf); + + //printf("done\n"); + +} + + + +/** + * Writes the specified byte to this output stream. + */ +void GzipOutputStream::put(int ch) +{ + if (closed) + { + //probably throw an exception here + return; + } + + + //Add char to buffer + inputBuf.push_back(ch); + totalIn++; + +} + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/io/gzipstream.h b/src/io/gzipstream.h new file mode 100644 index 000000000..adaf50967 --- /dev/null +++ b/src/io/gzipstream.h @@ -0,0 +1,121 @@ +#ifndef __INKSCAPE_IO_GZIPSTREAM_H__ +#define __INKSCAPE_IO_GZIPSTREAM_H__ +/** + * Zlib-enabled input and output streams + * + * This is a thin wrapper of libz calls, in order + * to provide a simple interface to our developers + * for gzip input and output. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" +#include <zlib.h> + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +/** + * This class is for deflating a gzip-compressed InputStream source + * + */ +class GzipInputStream : public BasicInputStream +{ + +public: + + GzipInputStream(InputStream &sourceStream); + + virtual ~GzipInputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + bool load(); + int fetchMore(); + + bool loaded; + + long totalIn; + long totalOut; + + unsigned char *outputBuf; + unsigned char *srcBuf; + + unsigned long crc; + unsigned long srcCrc; + unsigned long srcSiz; + unsigned long srcConsumed; + unsigned long srcLen; + long outputBufPos; + long outputBufLen; + + z_stream d_stream; +}; // class GzipInputStream + + + + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for gzip-compressing data going to the + * destination OutputStream + * + */ +class GzipOutputStream : public BasicOutputStream +{ + +public: + + GzipOutputStream(OutputStream &destinationStream); + + virtual ~GzipOutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + +private: + + std::vector<unsigned char> inputBuf; + + long totalIn; + long totalOut; + unsigned long crc; + +}; // class GzipOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_GZIPSTREAM_H__ */ diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp new file mode 100644 index 000000000..e527101f6 --- /dev/null +++ b/src/io/inkscapestream.cpp @@ -0,0 +1,842 @@ +/** + * Our base input/output stream classes. These are is directly + * inherited from iostreams, and includes any extra + * functionality that we might need. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest) +{ + for (;;) + { + int ch = source.get(); + if (ch<0) + break; + dest.put(ch); + } + dest.flush(); +} + +//######################################################################### +//# B A S I C I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +BasicInputStream::BasicInputStream(InputStream &sourceStream) + : source(sourceStream) +{ + closed = false; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int BasicInputStream::available() +{ + if (closed) + return 0; + return source.available(); +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void BasicInputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int BasicInputStream::get() +{ + if (closed) + return -1; + return source.get(); +} + + + +//######################################################################### +//# B A S I C O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +BasicOutputStream::BasicOutputStream(OutputStream &destinationStream) + : destination(destinationStream) +{ + closed = false; +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void BasicOutputStream::close() +{ + if (closed) + return; + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicOutputStream::flush() +{ + if (closed) + return; + destination.flush(); +} + +/** + * Writes the specified byte to this output stream. + */ +void BasicOutputStream::put(int ch) +{ + if (closed) + return; + destination.put(ch); +} + + + +//######################################################################### +//# B A S I C R E A D E R +//######################################################################### + + +/** + * + */ +BasicReader::BasicReader(Reader &sourceReader) +{ + source = &sourceReader; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this reader without blocking by the next caller of a method for + * this reader. + */ +int BasicReader::available() +{ + if (source) + return source->available(); + else + return 0; +} + + +/** + * Closes this reader and releases any system resources + * associated with the reader. + */ +void BasicReader::close() +{ + if (source) + source->close(); +} + +/** + * Reads the next byte of data from the reader. + */ +gunichar BasicReader::get() +{ + if (source) + return source->get(); + else + return (gunichar)-1; +} + + + + + + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readLine() +{ + Glib::ustring str; + while (available() > 0) + { + gunichar ch = get(); + if (ch == '\n') + break; + str.push_back(ch); + } + return str; +} + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readWord() +{ + Glib::ustring str; + while (available() > 0) + { + gunichar ch = get(); + if (!g_unichar_isprint(ch)) + break; + str.push_back(ch); + } + return str; +} + + +static bool getLong(Glib::ustring &str, long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + long ival = strtol(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getULong(Glib::ustring &str, unsigned long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + unsigned long ival = strtoul(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getDouble(Glib::ustring &str, double *val) +{ + const char *begin = str.raw().c_str(); + char *end; + double ival = strtod(begin, &end); + if (str == end) + return false; + *val = ival; + return true; +} + + + + + + + +/** + * + */ +const Reader &BasicReader::readBool (bool& val ) +{ + Glib::ustring buf = readWord(); + if (buf == "true") + val = true; + else + val = false; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readShort (short& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (short) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedShort (unsigned short& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned short) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readInt (int& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (int) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedInt (unsigned int& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned int) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readLong (long& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedLong (unsigned long& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readFloat (float& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = (float)ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readDouble (double& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = ival; + return *this; +} + + + +//######################################################################### +//# I N P U T S T R E A M R E A D E R +//######################################################################### + + +InputStreamReader::InputStreamReader(InputStream &inputStreamSource) + : inputStream(inputStreamSource) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void InputStreamReader::close() +{ + inputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +int InputStreamReader::available() +{ + return inputStream.available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +gunichar InputStreamReader::get() +{ + //Do we need conversions here? + gunichar ch = (gunichar)inputStream.get(); + return ch; +} + + + +//######################################################################### +//# S T D R E A D E R +//######################################################################### + + +/** + * + */ +StdReader::StdReader() +{ + inputStream = new StdInputStream(); +} + +/** + * + */ +StdReader::~StdReader() +{ + delete inputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdReader::close() +{ + inputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +int StdReader::available() +{ + return inputStream->available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +gunichar StdReader::get() +{ + //Do we need conversions here? + gunichar ch = (gunichar)inputStream->get(); + return ch; +} + + + + + +//######################################################################### +//# B A S I C W R I T E R +//######################################################################### + +/** + * + */ +BasicWriter::BasicWriter(Writer &destinationWriter) +{ + destination = &destinationWriter; +} + +/** + * Closes this writer and releases any system resources + * associated with this writer. + */ +void BasicWriter::close() +{ + if (destination) + destination->close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicWriter::flush() +{ + if (destination) + destination->flush(); +} + +/** + * Writes the specified byte to this output writer. + */ +void BasicWriter::put(gunichar ch) +{ + if (destination) + destination->put(ch); +} + +/** + * Provide printf()-like formatting + */ +Writer &BasicWriter::printf(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + gchar *buf = g_strdup_vprintf(fmt, args); + va_end(args); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} +/** + * Writes the specified character to this output writer. + */ +Writer &BasicWriter::writeChar(char ch) +{ + gunichar uch = ch; + put(uch); + return *this; +} + + +/** + * Writes the specified unicode string to this output writer. + */ +Writer &BasicWriter::writeUString(Glib::ustring &str) +{ + for (int i=0; i< (int)str.size(); i++) + put(str[i]); + return *this; +} + +/** + * Writes the specified standard string to this output writer. + */ +Writer &BasicWriter::writeStdString(std::string &str) +{ + Glib::ustring tmp(str); + writeUString(tmp); + return *this; +} + +/** + * Writes the specified character string to this output writer. + */ +Writer &BasicWriter::writeString(const char *str) +{ + Glib::ustring tmp; + if (str) + tmp = str; + else + tmp = "null"; + writeUString(tmp); + return *this; +} + + + + +/** + * + */ +Writer &BasicWriter::writeBool (bool val ) +{ + if (val) + writeString("true"); + else + writeString("false"); + return *this; +} + + +/** + * + */ +Writer &BasicWriter::writeShort (short val ) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + + + +/** + * + */ +Writer &BasicWriter::writeUnsignedShort (unsigned short val ) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeInt (int val) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedInt (unsigned int val) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeLong (long val) +{ + gchar *buf = g_strdup_printf("%ld", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedLong(unsigned long val) +{ + gchar *buf = g_strdup_printf("%lu", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeFloat(float val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeDouble(double val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + + +Writer& operator<< (Writer &writer, char val) + { return writer.writeChar(val); } + +Writer& operator<< (Writer &writer, Glib::ustring &val) + { return writer.writeUString(val); } + +Writer& operator<< (Writer &writer, std::string &val) + { return writer.writeStdString(val); } + +Writer& operator<< (Writer &writer, char *val) + { return writer.writeString(val); } + +Writer& operator<< (Writer &writer, bool val) + { return writer.writeBool(val); } + +Writer& operator<< (Writer &writer, short val) + { return writer.writeShort(val); } + +Writer& operator<< (Writer &writer, unsigned short val) + { return writer.writeUnsignedShort(val); } + +Writer& operator<< (Writer &writer, int val) + { return writer.writeInt(val); } + +Writer& operator<< (Writer &writer, unsigned int val) + { return writer.writeUnsignedInt(val); } + +Writer& operator<< (Writer &writer, long val) + { return writer.writeLong(val); } + +Writer& operator<< (Writer &writer, unsigned long val) + { return writer.writeUnsignedLong(val); } + +Writer& operator<< (Writer &writer, float val) + { return writer.writeFloat(val); } + +Writer& operator<< (Writer &writer, double val) + { return writer.writeDouble(val); } + + + +//######################################################################### +//# O U T P U T S T R E A M W R I T E R +//######################################################################### + + +OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest) + : outputStream(outputStreamDest) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void OutputStreamWriter::close() +{ + flush(); + outputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +void OutputStreamWriter::flush() +{ + outputStream.flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void OutputStreamWriter::put(gunichar ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream.put(intCh); +} + +//######################################################################### +//# S T D W R I T E R +//######################################################################### + + +/** + * + */ +StdWriter::StdWriter() +{ + outputStream = new StdOutputStream(); +} + + +/** + * + */ +StdWriter::~StdWriter() +{ + delete outputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdWriter::close() +{ + flush(); + outputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +void StdWriter::flush() +{ + outputStream->flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void StdWriter::put(gunichar ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream->put(intCh); +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h new file mode 100644 index 000000000..ad213dad9 --- /dev/null +++ b/src/io/inkscapestream.h @@ -0,0 +1,669 @@ +#ifndef __INKSCAPE_IO_INKSCAPESTREAM_H__ +#define __INKSCAPE_IO_INKSCAPESTREAM_H__ +/** + * Our base basic stream classes. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include <glibmm.h> + +namespace Inkscape +{ +namespace IO +{ + +class StreamException : public std::exception +{ +public: + + StreamException(const char *theReason) throw() + { reason = theReason; } + StreamException(Glib::ustring &theReason) throw() + { reason = theReason; } + ~StreamException() throw() + { } + char const *what() const throw() + { return reason.c_str(); } + +private: + Glib::ustring reason; + +}; + +//######################################################################### +//# I N P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an InputStream that is part of a chain should inherit from + * BasicInputStream. Inherit from this class to make a source endpoint, + * such as a URI or buffer. + * + */ +class InputStream +{ + +public: + + /** + * Constructor. + */ + InputStream() {} + + /** + * Destructor + */ + virtual ~InputStream() {} + + /** + * Return the number of bytes that are currently available + * to be read + */ + virtual int available() = 0; + + /** + * Do whatever it takes to 'close' this input stream + * The most likely implementation of this method will be + * for endpoints that use a resource for their data. + */ + virtual void close() = 0; + + /** + * Read one byte from this input stream. This is a blocking + * call. If no data is currently available, this call will + * not return until it exists. If the user does not want + * their code to block, then the usual solution is: + * if (available() > 0) + * myChar = get(); + * This call returns -1 on end-of-file. + */ + virtual int get() = 0; + +}; // class InputStream + + + + +/** + * This is the class that most users should inherit, to provide + * their own streams. + * + */ +class BasicInputStream : public InputStream +{ + +public: + + BasicInputStream(InputStream &sourceStream); + + virtual ~BasicInputStream() {} + + virtual int available(); + + virtual void close(); + + virtual int get(); + +protected: + + bool closed; + + InputStream &source; + +private: + + +}; // class BasicInputStream + + + +/** + * Convenience class for reading from standard input + */ +class StdInputStream : public InputStream +{ +public: + + int available() + { return 0; } + + void close() + { /* do nothing */ } + + int get() + { return getchar(); } + +}; + + + + + + +//######################################################################### +//# O U T P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an OutputStream that is part of a chain should inherit from + * BasicOutputStream. Inherit from this class to make a destination endpoint, + * such as a URI or buffer. + */ +class OutputStream +{ + +public: + + /** + * Constructor. + */ + OutputStream() {} + + /** + * Destructor + */ + virtual ~OutputStream() {} + + /** + * This call should + * 1. flush itself + * 2. close itself + * 3. close the destination stream + */ + virtual void close() = 0; + + /** + * This call should push any pending data it might have to + * the destination stream. It should NOT call flush() on + * the destination stream. + */ + virtual void flush() = 0; + + /** + * Send one byte to the destination stream. + */ + virtual void put(int ch) = 0; + + +}; // class OutputStream + + +/** + * This is the class that most users should inherit, to provide + * their own output streams. + */ +class BasicOutputStream : public OutputStream +{ + +public: + + BasicOutputStream(OutputStream &destinationStream); + + virtual ~BasicOutputStream() {} + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + +protected: + + bool closed; + + OutputStream &destination; + + +}; // class BasicOutputStream + + + +/** + * Convenience class for writing to standard output + */ +class StdOutputStream : public OutputStream +{ +public: + + void close() + { } + + void flush() + { } + + void put(int ch) + { putchar(ch); } + +}; + + + + +//######################################################################### +//# R E A D E R +//######################################################################### + + +/** + * This interface and its descendants are for unicode character-oriented input + * + */ +class Reader +{ + +public: + + /** + * Constructor. + */ + Reader() {} + + /** + * Destructor + */ + virtual ~Reader() {} + + + virtual int available() = 0; + + virtual void close() = 0; + + virtual gunichar get() = 0; + + virtual Glib::ustring readLine() = 0; + + virtual Glib::ustring readWord() = 0; + + /* Input formatting */ + virtual const Reader& readBool (bool& val ) = 0; + virtual const Reader& operator>> (bool& val ) = 0; + + virtual const Reader& readShort (short &val) = 0; + virtual const Reader& operator>> (short &val) = 0; + + virtual const Reader& readUnsignedShort (unsigned short &val) = 0; + virtual const Reader& operator>> (unsigned short &val) = 0; + + virtual const Reader& readInt (int &val) = 0; + virtual const Reader& operator>> (int &val) = 0; + + virtual const Reader& readUnsignedInt (unsigned int &val) = 0; + virtual const Reader& operator>> (unsigned int &val) = 0; + + virtual const Reader& readLong (long &val) = 0; + virtual const Reader& operator>> (long &val) = 0; + + virtual const Reader& readUnsignedLong (unsigned long &val) = 0; + virtual const Reader& operator>> (unsigned long &val) = 0; + + virtual const Reader& readFloat (float &val) = 0; + virtual const Reader& operator>> (float &val) = 0; + + virtual const Reader& readDouble (double &val) = 0; + virtual const Reader& operator>> (double &val) = 0; + +}; // interface Reader + + + +/** + * This class and its descendants are for unicode character-oriented input + * + */ +class BasicReader : public Reader +{ + +public: + + BasicReader(Reader &sourceStream); + + virtual ~BasicReader() {} + + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + virtual Glib::ustring readLine(); + + virtual Glib::ustring readWord(); + + /* Input formatting */ + virtual const Reader& readBool (bool& val ); + virtual const Reader& operator>> (bool& val ) + { return readBool(val); } + + virtual const Reader& readShort (short &val); + virtual const Reader& operator>> (short &val) + { return readShort(val); } + + virtual const Reader& readUnsignedShort (unsigned short &val); + virtual const Reader& operator>> (unsigned short &val) + { return readUnsignedShort(val); } + + virtual const Reader& readInt (int &val); + virtual const Reader& operator>> (int &val) + { return readInt(val); } + + virtual const Reader& readUnsignedInt (unsigned int &val); + virtual const Reader& operator>> (unsigned int &val) + { return readUnsignedInt(val); } + + virtual const Reader& readLong (long &val); + virtual const Reader& operator>> (long &val) + { return readLong(val); } + + virtual const Reader& readUnsignedLong (unsigned long &val); + virtual const Reader& operator>> (unsigned long &val) + { return readUnsignedLong(val); } + + virtual const Reader& readFloat (float &val); + virtual const Reader& operator>> (float &val) + { return readFloat(val); } + + virtual const Reader& readDouble (double &val); + virtual const Reader& operator>> (double &val) + { return readDouble(val); } + + +protected: + + Reader *source; + + BasicReader() + { source = NULL; } + +private: + +}; // class BasicReader + + + +/** + * Class for placing a Reader on an open InputStream + * + */ +class InputStreamReader : public BasicReader +{ +public: + + InputStreamReader(InputStream &inputStreamSource); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + +private: + + InputStream &inputStream; + + +}; + +/** + * Convenience class for reading formatted from standard input + * + */ +class StdReader : public BasicReader +{ +public: + + StdReader(); + + ~StdReader(); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + +private: + + InputStream *inputStream; + + +}; + + + + + +//######################################################################### +//# W R I T E R +//######################################################################### + +/** + * This interface and its descendants are for unicode character-oriented output + * + */ +class Writer +{ + +public: + + /** + * Constructor. + */ + Writer() {} + + /** + * Destructor + */ + virtual ~Writer() {} + + virtual void close() = 0; + + virtual void flush() = 0; + + virtual void put(gunichar ch) = 0; + + /* Formatted output */ + virtual Writer& printf(char *fmt, ...) = 0; + + virtual Writer& writeChar(char val) = 0; + + virtual Writer& writeUString(Glib::ustring &val) = 0; + + virtual Writer& writeStdString(std::string &val) = 0; + + virtual Writer& writeString(const char *str) = 0; + + virtual Writer& writeBool (bool val ) = 0; + + virtual Writer& writeShort (short val ) = 0; + + virtual Writer& writeUnsignedShort (unsigned short val ) = 0; + + virtual Writer& writeInt (int val ) = 0; + + virtual Writer& writeUnsignedInt (unsigned int val ) = 0; + + virtual Writer& writeLong (long val ) = 0; + + virtual Writer& writeUnsignedLong (unsigned long val ) = 0; + + virtual Writer& writeFloat (float val ) = 0; + + virtual Writer& writeDouble (double val ) = 0; + + + +}; // interface Writer + + +/** + * This class and its descendants are for unicode character-oriented output + * + */ +class BasicWriter : public Writer +{ + +public: + + BasicWriter(Writer &destinationWriter); + + virtual ~BasicWriter() {} + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(gunichar ch); + + + + /* Formatted output */ + virtual Writer &printf(char *fmt, ...); + + virtual Writer& writeChar(char val); + + virtual Writer& writeUString(Glib::ustring &val); + + virtual Writer& writeStdString(std::string &val); + + virtual Writer& writeString(const char *str); + + virtual Writer& writeBool (bool val ); + + virtual Writer& writeShort (short val ); + + virtual Writer& writeUnsignedShort (unsigned short val ); + + virtual Writer& writeInt (int val ); + + virtual Writer& writeUnsignedInt (unsigned int val ); + + virtual Writer& writeLong (long val ); + + virtual Writer& writeUnsignedLong (unsigned long val ); + + virtual Writer& writeFloat (float val ); + + virtual Writer& writeDouble (double val ); + + +protected: + + Writer *destination; + + BasicWriter() + { destination = NULL; } + +private: + +}; // class BasicWriter + + + +Writer& operator<< (Writer &writer, char val); + +Writer& operator<< (Writer &writer, Glib::ustring &val); + +Writer& operator<< (Writer &writer, std::string &val); + +Writer& operator<< (Writer &writer, char *val); + +Writer& operator<< (Writer &writer, bool val); + +Writer& operator<< (Writer &writer, short val); + +Writer& operator<< (Writer &writer, unsigned short val); + +Writer& operator<< (Writer &writer, int val); + +Writer& operator<< (Writer &writer, unsigned int val); + +Writer& operator<< (Writer &writer, long val); + +Writer& operator<< (Writer &writer, unsigned long val); + +Writer& operator<< (Writer &writer, float val); + +Writer& operator<< (Writer &writer, double val); + + + + +/** + * Class for placing a Writer on an open OutputStream + * + */ +class OutputStreamWriter : public BasicWriter +{ +public: + + OutputStreamWriter(OutputStream &outputStreamDest); + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(gunichar ch); + + +private: + + OutputStream &outputStream; + + +}; + + +/** + * Convenience class for writing to standard output + */ +class StdWriter : public BasicWriter +{ +public: + StdWriter(); + + ~StdWriter(); + + + virtual void close(); + + + virtual void flush(); + + + virtual void put(gunichar ch); + + +private: + + OutputStream *outputStream; + +}; + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest); + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_INKSCAPESTREAM_H__ */ diff --git a/src/io/makefile.in b/src/io/makefile.in new file mode 100644 index 000000000..61ee7437f --- /dev/null +++ b/src/io/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) io/all + +clean %.a %.o: + cd .. && $(MAKE) io/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/io/simple-sax.cpp b/src/io/simple-sax.cpp new file mode 100644 index 000000000..2dd78b451 --- /dev/null +++ b/src/io/simple-sax.cpp @@ -0,0 +1,1493 @@ +/* + * SimpleSAX + * + * Authors: + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2004 AUTHORS + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "simple-sax.h" + +namespace Inkscape { +namespace IO { + +SaxHandler::SaxHandler() +{ + memset( &sax, 0, sizeof(sax) ); + sax.startDocument = startDocument; + sax.endDocument = endDocument; + sax.startElement = startElement; + sax.endElement = endElement; + sax.characters = characters; +} + +SaxHandler::~SaxHandler() +{ +} + + +static int xmlErrorVals[] = { + XML_ERR_OK, + XML_ERR_INTERNAL_ERROR, + XML_ERR_NO_MEMORY, + XML_ERR_DOCUMENT_START, + XML_ERR_DOCUMENT_EMPTY, + XML_ERR_DOCUMENT_END, + XML_ERR_INVALID_HEX_CHARREF, + XML_ERR_INVALID_DEC_CHARREF, + XML_ERR_INVALID_CHARREF, + XML_ERR_INVALID_CHAR, + XML_ERR_CHARREF_AT_EOF, + XML_ERR_CHARREF_IN_PROLOG, + XML_ERR_CHARREF_IN_EPILOG, + XML_ERR_CHARREF_IN_DTD, + XML_ERR_ENTITYREF_AT_EOF, + XML_ERR_ENTITYREF_IN_PROLOG, + XML_ERR_ENTITYREF_IN_EPILOG, + XML_ERR_ENTITYREF_IN_DTD, + XML_ERR_PEREF_AT_EOF, + XML_ERR_PEREF_IN_PROLOG, + XML_ERR_PEREF_IN_EPILOG, + XML_ERR_PEREF_IN_INT_SUBSET, + XML_ERR_ENTITYREF_NO_NAME, + XML_ERR_ENTITYREF_SEMICOL_MISSING, + XML_ERR_PEREF_NO_NAME, + XML_ERR_PEREF_SEMICOL_MISSING, + XML_ERR_UNDECLARED_ENTITY, + XML_WAR_UNDECLARED_ENTITY, + XML_ERR_UNPARSED_ENTITY, + XML_ERR_ENTITY_IS_EXTERNAL, + XML_ERR_ENTITY_IS_PARAMETER, + XML_ERR_UNKNOWN_ENCODING, + XML_ERR_UNSUPPORTED_ENCODING, + XML_ERR_STRING_NOT_STARTED, + XML_ERR_STRING_NOT_CLOSED, + XML_ERR_NS_DECL_ERROR, + XML_ERR_ENTITY_NOT_STARTED, + XML_ERR_ENTITY_NOT_FINISHED, + XML_ERR_LT_IN_ATTRIBUTE, + XML_ERR_ATTRIBUTE_NOT_STARTED, + XML_ERR_ATTRIBUTE_NOT_FINISHED, + XML_ERR_ATTRIBUTE_WITHOUT_VALUE, + XML_ERR_ATTRIBUTE_REDEFINED, + XML_ERR_LITERAL_NOT_STARTED, + XML_ERR_LITERAL_NOT_FINISHED, + XML_ERR_COMMENT_NOT_FINISHED, + XML_ERR_PI_NOT_STARTED, + XML_ERR_PI_NOT_FINISHED, + XML_ERR_NOTATION_NOT_STARTED, + XML_ERR_NOTATION_NOT_FINISHED, + XML_ERR_ATTLIST_NOT_STARTED, + XML_ERR_ATTLIST_NOT_FINISHED, + XML_ERR_MIXED_NOT_STARTED, + XML_ERR_MIXED_NOT_FINISHED, + XML_ERR_ELEMCONTENT_NOT_STARTED, + XML_ERR_ELEMCONTENT_NOT_FINISHED, + XML_ERR_XMLDECL_NOT_STARTED, + XML_ERR_XMLDECL_NOT_FINISHED, + XML_ERR_CONDSEC_NOT_STARTED, + XML_ERR_CONDSEC_NOT_FINISHED, + XML_ERR_EXT_SUBSET_NOT_FINISHED, + XML_ERR_DOCTYPE_NOT_FINISHED, + XML_ERR_MISPLACED_CDATA_END, + XML_ERR_CDATA_NOT_FINISHED, + XML_ERR_RESERVED_XML_NAME, + XML_ERR_SPACE_REQUIRED, + XML_ERR_SEPARATOR_REQUIRED, + XML_ERR_NMTOKEN_REQUIRED, + XML_ERR_NAME_REQUIRED, + XML_ERR_PCDATA_REQUIRED, + XML_ERR_URI_REQUIRED, + XML_ERR_PUBID_REQUIRED, + XML_ERR_LT_REQUIRED, + XML_ERR_GT_REQUIRED, + XML_ERR_LTSLASH_REQUIRED, + XML_ERR_EQUAL_REQUIRED, + XML_ERR_TAG_NAME_MISMATCH, + XML_ERR_TAG_NOT_FINISHED, + XML_ERR_STANDALONE_VALUE, + XML_ERR_ENCODING_NAME, + XML_ERR_HYPHEN_IN_COMMENT, + XML_ERR_INVALID_ENCODING, + XML_ERR_EXT_ENTITY_STANDALONE, + XML_ERR_CONDSEC_INVALID, + XML_ERR_VALUE_REQUIRED, + XML_ERR_NOT_WELL_BALANCED, + XML_ERR_EXTRA_CONTENT, + XML_ERR_ENTITY_CHAR_ERROR, + XML_ERR_ENTITY_PE_INTERNAL, + XML_ERR_ENTITY_LOOP, + XML_ERR_ENTITY_BOUNDARY, + XML_ERR_INVALID_URI, + XML_ERR_URI_FRAGMENT, + XML_WAR_CATALOG_PI, + XML_ERR_NO_DTD, + XML_ERR_CONDSEC_INVALID_KEYWORD, + XML_ERR_VERSION_MISSING, + XML_WAR_UNKNOWN_VERSION, + XML_WAR_LANG_VALUE, + XML_WAR_NS_URI, + XML_WAR_NS_URI_RELATIVE, + XML_ERR_MISSING_ENCODING, + XML_NS_ERR_XML_NAMESPACE, + XML_NS_ERR_UNDEFINED_NAMESPACE, + XML_NS_ERR_QNAME, + XML_NS_ERR_ATTRIBUTE_REDEFINED, + XML_DTD_ATTRIBUTE_DEFAULT, + XML_DTD_ATTRIBUTE_REDEFINED, + XML_DTD_ATTRIBUTE_VALUE, + XML_DTD_CONTENT_ERROR, + XML_DTD_CONTENT_MODEL, + XML_DTD_CONTENT_NOT_DETERMINIST, + XML_DTD_DIFFERENT_PREFIX, + XML_DTD_ELEM_DEFAULT_NAMESPACE, + XML_DTD_ELEM_NAMESPACE, + XML_DTD_ELEM_REDEFINED, + XML_DTD_EMPTY_NOTATION, + XML_DTD_ENTITY_TYPE, + XML_DTD_ID_FIXED, + XML_DTD_ID_REDEFINED, + XML_DTD_ID_SUBSET, + XML_DTD_INVALID_CHILD, + XML_DTD_INVALID_DEFAULT, + XML_DTD_LOAD_ERROR, + XML_DTD_MISSING_ATTRIBUTE, + XML_DTD_MIXED_CORRUPT, + XML_DTD_MULTIPLE_ID, + XML_DTD_NO_DOC, + XML_DTD_NO_DTD, + XML_DTD_NO_ELEM_NAME, + XML_DTD_NO_PREFIX, + XML_DTD_NO_ROOT, + XML_DTD_NOTATION_REDEFINED, + XML_DTD_NOTATION_VALUE, + XML_DTD_NOT_EMPTY, + XML_DTD_NOT_PCDATA, + XML_DTD_NOT_STANDALONE, + XML_DTD_ROOT_NAME, + XML_DTD_STANDALONE_WHITE_SPACE, + XML_DTD_UNKNOWN_ATTRIBUTE, + XML_DTD_UNKNOWN_ELEM, + XML_DTD_UNKNOWN_ENTITY, + XML_DTD_UNKNOWN_ID, + XML_DTD_UNKNOWN_NOTATION, + XML_DTD_STANDALONE_DEFAULTED, + XML_DTD_XMLID_VALUE, + XML_DTD_XMLID_TYPE, + XML_HTML_STRUCURE_ERROR, + XML_HTML_UNKNOWN_TAG, + XML_RNGP_ANYNAME_ATTR_ANCESTOR, + XML_RNGP_ATTR_CONFLICT, + XML_RNGP_ATTRIBUTE_CHILDREN, + XML_RNGP_ATTRIBUTE_CONTENT, + XML_RNGP_ATTRIBUTE_EMPTY, + XML_RNGP_ATTRIBUTE_NOOP, + XML_RNGP_CHOICE_CONTENT, + XML_RNGP_CHOICE_EMPTY, + XML_RNGP_CREATE_FAILURE, + XML_RNGP_DATA_CONTENT, + XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, + XML_RNGP_DEFINE_CREATE_FAILED, + XML_RNGP_DEFINE_EMPTY, + XML_RNGP_DEFINE_MISSING, + XML_RNGP_DEFINE_NAME_MISSING, + XML_RNGP_ELEM_CONTENT_EMPTY, + XML_RNGP_ELEM_CONTENT_ERROR, + XML_RNGP_ELEMENT_EMPTY, + XML_RNGP_ELEMENT_CONTENT, + XML_RNGP_ELEMENT_NAME, + XML_RNGP_ELEMENT_NO_CONTENT, + XML_RNGP_ELEM_TEXT_CONFLICT, + XML_RNGP_EMPTY, + XML_RNGP_EMPTY_CONSTRUCT, + XML_RNGP_EMPTY_CONTENT, + XML_RNGP_EMPTY_NOT_EMPTY, + XML_RNGP_ERROR_TYPE_LIB, + XML_RNGP_EXCEPT_EMPTY, + XML_RNGP_EXCEPT_MISSING, + XML_RNGP_EXCEPT_MULTIPLE, + XML_RNGP_EXCEPT_NO_CONTENT, + XML_RNGP_EXTERNALREF_EMTPY, + XML_RNGP_EXTERNAL_REF_FAILURE, + XML_RNGP_EXTERNALREF_RECURSE, + XML_RNGP_FORBIDDEN_ATTRIBUTE, + XML_RNGP_FOREIGN_ELEMENT, + XML_RNGP_GRAMMAR_CONTENT, + XML_RNGP_GRAMMAR_EMPTY, + XML_RNGP_GRAMMAR_MISSING, + XML_RNGP_GRAMMAR_NO_START, + XML_RNGP_GROUP_ATTR_CONFLICT, + XML_RNGP_HREF_ERROR, + XML_RNGP_INCLUDE_EMPTY, + XML_RNGP_INCLUDE_FAILURE, + XML_RNGP_INCLUDE_RECURSE, + XML_RNGP_INTERLEAVE_ADD, + XML_RNGP_INTERLEAVE_CREATE_FAILED, + XML_RNGP_INTERLEAVE_EMPTY, + XML_RNGP_INTERLEAVE_NO_CONTENT, + XML_RNGP_INVALID_DEFINE_NAME, + XML_RNGP_INVALID_URI, + XML_RNGP_INVALID_VALUE, + XML_RNGP_MISSING_HREF, + XML_RNGP_NAME_MISSING, + XML_RNGP_NEED_COMBINE, + XML_RNGP_NOTALLOWED_NOT_EMPTY, + XML_RNGP_NSNAME_ATTR_ANCESTOR, + XML_RNGP_NSNAME_NO_NS, + XML_RNGP_PARAM_FORBIDDEN, + XML_RNGP_PARAM_NAME_MISSING, + XML_RNGP_PARENTREF_CREATE_FAILED, + XML_RNGP_PARENTREF_NAME_INVALID, + XML_RNGP_PARENTREF_NO_NAME, + XML_RNGP_PARENTREF_NO_PARENT, + XML_RNGP_PARENTREF_NOT_EMPTY, + XML_RNGP_PARSE_ERROR, + XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, + XML_RNGP_PAT_ATTR_ATTR, + XML_RNGP_PAT_ATTR_ELEM, + XML_RNGP_PAT_DATA_EXCEPT_ATTR, + XML_RNGP_PAT_DATA_EXCEPT_ELEM, + XML_RNGP_PAT_DATA_EXCEPT_EMPTY, + XML_RNGP_PAT_DATA_EXCEPT_GROUP, + XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, + XML_RNGP_PAT_DATA_EXCEPT_LIST, + XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, + XML_RNGP_PAT_DATA_EXCEPT_REF, + XML_RNGP_PAT_DATA_EXCEPT_TEXT, + XML_RNGP_PAT_LIST_ATTR, + XML_RNGP_PAT_LIST_ELEM, + XML_RNGP_PAT_LIST_INTERLEAVE, + XML_RNGP_PAT_LIST_LIST, + XML_RNGP_PAT_LIST_REF, + XML_RNGP_PAT_LIST_TEXT, + XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, + XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, + XML_RNGP_PAT_ONEMORE_GROUP_ATTR, + XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, + XML_RNGP_PAT_START_ATTR, + XML_RNGP_PAT_START_DATA, + XML_RNGP_PAT_START_EMPTY, + XML_RNGP_PAT_START_GROUP, + XML_RNGP_PAT_START_INTERLEAVE, + XML_RNGP_PAT_START_LIST, + XML_RNGP_PAT_START_ONEMORE, + XML_RNGP_PAT_START_TEXT, + XML_RNGP_PAT_START_VALUE, + XML_RNGP_PREFIX_UNDEFINED, + XML_RNGP_REF_CREATE_FAILED, + XML_RNGP_REF_CYCLE, + XML_RNGP_REF_NAME_INVALID, + XML_RNGP_REF_NO_DEF, + XML_RNGP_REF_NO_NAME, + XML_RNGP_REF_NOT_EMPTY, + XML_RNGP_START_CHOICE_AND_INTERLEAVE, + XML_RNGP_START_CONTENT, + XML_RNGP_START_EMPTY, + XML_RNGP_START_MISSING, + XML_RNGP_TEXT_EXPECTED, + XML_RNGP_TEXT_HAS_CHILD, + XML_RNGP_TYPE_MISSING, + XML_RNGP_TYPE_NOT_FOUND, + XML_RNGP_TYPE_VALUE, + XML_RNGP_UNKNOWN_ATTRIBUTE, + XML_RNGP_UNKNOWN_COMBINE, + XML_RNGP_UNKNOWN_CONSTRUCT, + XML_RNGP_UNKNOWN_TYPE_LIB, + XML_RNGP_URI_FRAGMENT, + XML_RNGP_URI_NOT_ABSOLUTE, + XML_RNGP_VALUE_EMPTY, + XML_RNGP_VALUE_NO_CONTENT, + XML_RNGP_XMLNS_NAME, + XML_RNGP_XML_NS, + XML_XPATH_EXPRESSION_OK, + XML_XPATH_NUMBER_ERROR, + XML_XPATH_UNFINISHED_LITERAL_ERROR, + XML_XPATH_START_LITERAL_ERROR, + XML_XPATH_VARIABLE_REF_ERROR, + XML_XPATH_UNDEF_VARIABLE_ERROR, + XML_XPATH_INVALID_PREDICATE_ERROR, + XML_XPATH_EXPR_ERROR, + XML_XPATH_UNCLOSED_ERROR, + XML_XPATH_UNKNOWN_FUNC_ERROR, + XML_XPATH_INVALID_OPERAND, + XML_XPATH_INVALID_TYPE, + XML_XPATH_INVALID_ARITY, + XML_XPATH_INVALID_CTXT_SIZE, + XML_XPATH_INVALID_CTXT_POSITION, + XML_XPATH_MEMORY_ERROR, + XML_XPTR_SYNTAX_ERROR, + XML_XPTR_RESOURCE_ERROR, + XML_XPTR_SUB_RESOURCE_ERROR, + XML_XPATH_UNDEF_PREFIX_ERROR, + XML_XPATH_ENCODING_ERROR, + XML_XPATH_INVALID_CHAR_ERROR, + XML_TREE_INVALID_HEX, + XML_TREE_INVALID_DEC, + XML_TREE_UNTERMINATED_ENTITY, + XML_SAVE_NOT_UTF8, + XML_SAVE_CHAR_INVALID, + XML_SAVE_NO_DOCTYPE, + XML_SAVE_UNKNOWN_ENCODING, + XML_REGEXP_COMPILE_ERROR, + XML_IO_UNKNOWN, + XML_IO_EACCES, + XML_IO_EAGAIN, + XML_IO_EBADF, + XML_IO_EBADMSG, + XML_IO_EBUSY, + XML_IO_ECANCELED, + XML_IO_ECHILD, + XML_IO_EDEADLK, + XML_IO_EDOM, + XML_IO_EEXIST, + XML_IO_EFAULT, + XML_IO_EFBIG, + XML_IO_EINPROGRESS, + XML_IO_EINTR, + XML_IO_EINVAL, + XML_IO_EIO, + XML_IO_EISDIR, + XML_IO_EMFILE, + XML_IO_EMLINK, + XML_IO_EMSGSIZE, + XML_IO_ENAMETOOLONG, + XML_IO_ENFILE, + XML_IO_ENODEV, + XML_IO_ENOENT, + XML_IO_ENOEXEC, + XML_IO_ENOLCK, + XML_IO_ENOMEM, + XML_IO_ENOSPC, + XML_IO_ENOSYS, + XML_IO_ENOTDIR, + XML_IO_ENOTEMPTY, + XML_IO_ENOTSUP, + XML_IO_ENOTTY, + XML_IO_ENXIO, + XML_IO_EPERM, + XML_IO_EPIPE, + XML_IO_ERANGE, + XML_IO_EROFS, + XML_IO_ESPIPE, + XML_IO_ESRCH, + XML_IO_ETIMEDOUT, + XML_IO_EXDEV, + XML_IO_NETWORK_ATTEMPT, + XML_IO_ENCODER, + XML_IO_FLUSH, + XML_IO_WRITE, + XML_IO_NO_INPUT, + XML_IO_BUFFER_FULL, + XML_IO_LOAD_ERROR, + XML_IO_ENOTSOCK, + XML_IO_EISCONN, + XML_IO_ECONNREFUSED, + XML_IO_ENETUNREACH, + XML_IO_EADDRINUSE, + XML_IO_EALREADY, + XML_IO_EAFNOSUPPORT, + XML_XINCLUDE_RECURSION, + XML_XINCLUDE_PARSE_VALUE, + XML_XINCLUDE_ENTITY_DEF_MISMATCH, + XML_XINCLUDE_NO_HREF, + XML_XINCLUDE_NO_FALLBACK, + XML_XINCLUDE_HREF_URI, + XML_XINCLUDE_TEXT_FRAGMENT, + XML_XINCLUDE_TEXT_DOCUMENT, + XML_XINCLUDE_INVALID_CHAR, + XML_XINCLUDE_BUILD_FAILED, + XML_XINCLUDE_UNKNOWN_ENCODING, + XML_XINCLUDE_MULTIPLE_ROOT, + XML_XINCLUDE_XPTR_FAILED, + XML_XINCLUDE_XPTR_RESULT, + XML_XINCLUDE_INCLUDE_IN_INCLUDE, + XML_XINCLUDE_FALLBACKS_IN_INCLUDE, + XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, + XML_XINCLUDE_DEPRECATED_NS, + XML_XINCLUDE_FRAGMENT_ID, + XML_CATALOG_MISSING_ATTR, + XML_CATALOG_ENTRY_BROKEN, + XML_CATALOG_PREFER_VALUE, + XML_CATALOG_NOT_CATALOG, + XML_CATALOG_RECURSION, + XML_SCHEMAP_PREFIX_UNDEFINED, + XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, + XML_SCHEMAP_ATTRGRP_NONAME_NOREF, + XML_SCHEMAP_ATTR_NONAME_NOREF, + XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, + XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, + XML_SCHEMAP_ELEM_NONAME_NOREF, + XML_SCHEMAP_EXTENSION_NO_BASE, + XML_SCHEMAP_FACET_NO_VALUE, + XML_SCHEMAP_FAILED_BUILD_IMPORT, + XML_SCHEMAP_GROUP_NONAME_NOREF, + XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, + XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, + XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, + XML_SCHEMAP_INVALID_BOOLEAN, + XML_SCHEMAP_INVALID_ENUM, + XML_SCHEMAP_INVALID_FACET, + XML_SCHEMAP_INVALID_FACET_VALUE, + XML_SCHEMAP_INVALID_MAXOCCURS, + XML_SCHEMAP_INVALID_MINOCCURS, + XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, + XML_SCHEMAP_INVALID_WHITE_SPACE, + XML_SCHEMAP_NOATTR_NOREF, + XML_SCHEMAP_NOTATION_NO_NAME, + XML_SCHEMAP_NOTYPE_NOREF, + XML_SCHEMAP_REF_AND_SUBTYPE, + XML_SCHEMAP_RESTRICTION_NONAME_NOREF, + XML_SCHEMAP_SIMPLETYPE_NONAME, + XML_SCHEMAP_TYPE_AND_SUBTYPE, + XML_SCHEMAP_UNKNOWN_ALL_CHILD, + XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, + XML_SCHEMAP_UNKNOWN_ATTR_CHILD, + XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, + XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, + XML_SCHEMAP_UNKNOWN_BASE_TYPE, + XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, + XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, + XML_SCHEMAP_UNKNOWN_ELEM_CHILD, + XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, + XML_SCHEMAP_UNKNOWN_FACET_CHILD, + XML_SCHEMAP_UNKNOWN_FACET_TYPE, + XML_SCHEMAP_UNKNOWN_GROUP_CHILD, + XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, + XML_SCHEMAP_UNKNOWN_LIST_CHILD, + XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, + XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_REF, + XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, + XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, + XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, + XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, + XML_SCHEMAP_UNKNOWN_TYPE, + XML_SCHEMAP_UNKNOWN_UNION_CHILD, + XML_SCHEMAP_ELEM_DEFAULT_FIXED, + XML_SCHEMAP_REGEXP_INVALID, + XML_SCHEMAP_FAILED_LOAD, + XML_SCHEMAP_NOTHING_TO_PARSE, + XML_SCHEMAP_NOROOT, + XML_SCHEMAP_REDEFINED_GROUP, + XML_SCHEMAP_REDEFINED_TYPE, + XML_SCHEMAP_REDEFINED_ELEMENT, + XML_SCHEMAP_REDEFINED_ATTRGROUP, + XML_SCHEMAP_REDEFINED_ATTR, + XML_SCHEMAP_REDEFINED_NOTATION, + XML_SCHEMAP_FAILED_PARSE, + XML_SCHEMAP_UNKNOWN_PREFIX, + XML_SCHEMAP_DEF_AND_PREFIX, + XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, + XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, + XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, + XML_SCHEMAP_NOT_SCHEMA, + XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, + XML_SCHEMAP_INVALID_ATTR_USE, + XML_SCHEMAP_RECURSIVE, + XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, + XML_SCHEMAP_INVALID_ATTR_COMBINATION, + XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, + XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, + XML_SCHEMAP_INVALID_ATTR_NAME, + XML_SCHEMAP_REF_AND_CONTENT, + XML_SCHEMAP_CT_PROPS_CORRECT_1, + XML_SCHEMAP_CT_PROPS_CORRECT_2, + XML_SCHEMAP_CT_PROPS_CORRECT_3, + XML_SCHEMAP_CT_PROPS_CORRECT_4, + XML_SCHEMAP_CT_PROPS_CORRECT_5, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, + XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, + XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, + XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, + XML_SCHEMAP_SRC_IMPORT_3_1, + XML_SCHEMAP_SRC_IMPORT_3_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, + XML_SCHEMAP_COS_CT_EXTENDS_1_3, + XML_SCHEMAV_NOROOT, + XML_SCHEMAV_UNDECLAREDELEM, + XML_SCHEMAV_NOTTOPLEVEL, + XML_SCHEMAV_MISSING, + XML_SCHEMAV_WRONGELEM, + XML_SCHEMAV_NOTYPE, + XML_SCHEMAV_NOROLLBACK, + XML_SCHEMAV_ISABSTRACT, + XML_SCHEMAV_NOTEMPTY, + XML_SCHEMAV_ELEMCONT, + XML_SCHEMAV_HAVEDEFAULT, + XML_SCHEMAV_NOTNILLABLE, + XML_SCHEMAV_EXTRACONTENT, + XML_SCHEMAV_INVALIDATTR, + XML_SCHEMAV_INVALIDELEM, + XML_SCHEMAV_NOTDETERMINIST, + XML_SCHEMAV_CONSTRUCT, + XML_SCHEMAV_INTERNAL, + XML_SCHEMAV_NOTSIMPLE, + XML_SCHEMAV_ATTRUNKNOWN, + XML_SCHEMAV_ATTRINVALID, + XML_SCHEMAV_VALUE, + XML_SCHEMAV_FACET, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, + XML_SCHEMAV_CVC_TYPE_3_1_1, + XML_SCHEMAV_CVC_TYPE_3_1_2, + XML_SCHEMAV_CVC_FACET_VALID, + XML_SCHEMAV_CVC_LENGTH_VALID, + XML_SCHEMAV_CVC_MINLENGTH_VALID, + XML_SCHEMAV_CVC_MAXLENGTH_VALID, + XML_SCHEMAV_CVC_MININCLUSIVE_VALID, + XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, + XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, + XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, + XML_SCHEMAV_CVC_TOTALDIGITS_VALID, + XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, + XML_SCHEMAV_CVC_PATTERN_VALID, + XML_SCHEMAV_CVC_ENUMERATION_VALID, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, + +#if defined XML_SCHEMAV_CVC_ELT_1 + XML_SCHEMAV_CVC_ELT_1, + XML_SCHEMAV_CVC_ELT_2, + XML_SCHEMAV_CVC_ELT_3_1, + XML_SCHEMAV_CVC_ELT_3_2_1, + XML_SCHEMAV_CVC_ELT_3_2_2, + XML_SCHEMAV_CVC_ELT_4_1, + XML_SCHEMAV_CVC_ELT_4_2, + XML_SCHEMAV_CVC_ELT_4_3, + XML_SCHEMAV_CVC_ELT_5_1_1, + XML_SCHEMAV_CVC_ELT_5_1_2, + XML_SCHEMAV_CVC_ELT_5_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_2_2, + XML_SCHEMAV_CVC_ELT_6, + XML_SCHEMAV_CVC_ELT_7, + XML_SCHEMAV_CVC_ATTRIBUTE_1, + XML_SCHEMAV_CVC_ATTRIBUTE_2, + XML_SCHEMAV_CVC_ATTRIBUTE_3, + XML_SCHEMAV_CVC_ATTRIBUTE_4, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, + XML_SCHEMAV_CVC_COMPLEX_TYPE_4, + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, + XML_SCHEMAV_ELEMENT_CONTENT, + XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, +#endif + +#if defined XML_SCHEMAV_CVC_COMPLEX_TYPE_1 + XML_SCHEMAV_CVC_COMPLEX_TYPE_1, + XML_SCHEMAV_CVC_AU, + XML_SCHEMAV_CVC_TYPE_1, + XML_SCHEMAV_CVC_TYPE_2, +#endif + + XML_XPTR_UNKNOWN_SCHEME, + XML_XPTR_CHILDSEQ_START, + XML_XPTR_EVAL_FAILED, + XML_XPTR_EXTRA_OBJECTS, + XML_C14N_CREATE_CTXT, + XML_C14N_REQUIRES_UTF8, + XML_C14N_CREATE_STACK, + XML_C14N_INVALID_NODE, + XML_FTP_PASV_ANSWER, + XML_FTP_EPSV_ANSWER, + XML_FTP_ACCNT, + XML_HTTP_URL_SYNTAX, + XML_HTTP_USE_IP, + XML_HTTP_UNKNOWN_HOST, + XML_SCHEMAP_SRC_SIMPLE_TYPE_1, + XML_SCHEMAP_SRC_SIMPLE_TYPE_2, + XML_SCHEMAP_SRC_SIMPLE_TYPE_3, + XML_SCHEMAP_SRC_SIMPLE_TYPE_4, + XML_SCHEMAP_SRC_RESOLVE, + XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, + XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, + XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, + XML_SCHEMAP_ST_PROPS_CORRECT_1, + XML_SCHEMAP_ST_PROPS_CORRECT_2, + XML_SCHEMAP_ST_PROPS_CORRECT_3, + XML_SCHEMAP_COS_ST_RESTRICTS_1_1, + XML_SCHEMAP_COS_ST_RESTRICTS_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, + XML_SCHEMAP_COS_ST_RESTRICTS_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, + XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, + XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, + XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, + XML_SCHEMAP_S4S_ELEM_MISSING, + XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, + XML_SCHEMAP_S4S_ATTR_MISSING, + +#if defined XML_SCHEMAP_S4S_ATTR_INVALID_VALUE + XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, + XML_SCHEMAP_SRC_ELEMENT_1, + XML_SCHEMAP_SRC_ELEMENT_2_1, + XML_SCHEMAP_SRC_ELEMENT_2_2, + XML_SCHEMAP_SRC_ELEMENT_3, + XML_SCHEMAP_P_PROPS_CORRECT_1, + XML_SCHEMAP_P_PROPS_CORRECT_2_1, + XML_SCHEMAP_P_PROPS_CORRECT_2_2, + XML_SCHEMAP_E_PROPS_CORRECT_2, + XML_SCHEMAP_E_PROPS_CORRECT_3, + XML_SCHEMAP_E_PROPS_CORRECT_4, + XML_SCHEMAP_E_PROPS_CORRECT_5, + XML_SCHEMAP_E_PROPS_CORRECT_6, + XML_SCHEMAP_SRC_INCLUDE, + XML_SCHEMAP_SRC_ATTRIBUTE_1, + XML_SCHEMAP_SRC_ATTRIBUTE_2, + XML_SCHEMAP_SRC_ATTRIBUTE_3_1, + XML_SCHEMAP_SRC_ATTRIBUTE_3_2, + XML_SCHEMAP_SRC_ATTRIBUTE_4, + XML_SCHEMAP_NO_XMLNS, + XML_SCHEMAP_NO_XSI, + XML_SCHEMAP_COS_VALID_DEFAULT_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, + XML_SCHEMAP_CVC_SIMPLE_TYPE, + XML_SCHEMAP_COS_CT_EXTENDS_1_1, + XML_SCHEMAP_SRC_IMPORT_1_1, + XML_SCHEMAP_SRC_IMPORT_1_2, + XML_SCHEMAP_SRC_IMPORT_2, + XML_SCHEMAP_SRC_IMPORT_2_1, + XML_SCHEMAP_SRC_IMPORT_2_2, +#endif + +#if defined XML_SCHEMAP_INTERNAL + XML_SCHEMAP_INTERNAL, + XML_SCHEMAP_NOT_DETERMINISTIC, +#endif + +#if defined XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1 + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, + XML_SCHEMAP_MG_PROPS_CORRECT_1, + XML_SCHEMAP_MG_PROPS_CORRECT_2, + XML_SCHEMAP_SRC_CT_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, + XML_SCHEMAP_AU_PROPS_CORRECT_2, + XML_SCHEMAP_A_PROPS_CORRECT_2, +#endif + -1 +}; + + +static const char* xmlErrorStrs[] = { + "ERR_OK", + "ERR_INTERNAL_ERROR", + "ERR_NO_MEMORY", + "ERR_DOCUMENT_START", + "ERR_DOCUMENT_EMPTY", + "ERR_DOCUMENT_END", + "ERR_INVALID_HEX_CHARREF", + "ERR_INVALID_DEC_CHARREF", + "ERR_INVALID_CHARREF", + "ERR_INVALID_CHAR", + "ERR_CHARREF_AT_EOF", + "ERR_CHARREF_IN_PROLOG", + "ERR_CHARREF_IN_EPILOG", + "ERR_CHARREF_IN_DTD", + "ERR_ENTITYREF_AT_EOF", + "ERR_ENTITYREF_IN_PROLOG", + "ERR_ENTITYREF_IN_EPILOG", + "ERR_ENTITYREF_IN_DTD", + "ERR_PEREF_AT_EOF", + "ERR_PEREF_IN_PROLOG", + "ERR_PEREF_IN_EPILOG", + "ERR_PEREF_IN_INT_SUBSET", + "ERR_ENTITYREF_NO_NAME", + "ERR_ENTITYREF_SEMICOL_MISSING", + "ERR_PEREF_NO_NAME", + "ERR_PEREF_SEMICOL_MISSING", + "ERR_UNDECLARED_ENTITY", + "WAR_UNDECLARED_ENTITY", + "ERR_UNPARSED_ENTITY", + "ERR_ENTITY_IS_EXTERNAL", + "ERR_ENTITY_IS_PARAMETER", + "ERR_UNKNOWN_ENCODING", + "ERR_UNSUPPORTED_ENCODING", + "ERR_STRING_NOT_STARTED", + "ERR_STRING_NOT_CLOSED", + "ERR_NS_DECL_ERROR", + "ERR_ENTITY_NOT_STARTED", + "ERR_ENTITY_NOT_FINISHED", + "ERR_LT_IN_ATTRIBUTE", + "ERR_ATTRIBUTE_NOT_STARTED", + "ERR_ATTRIBUTE_NOT_FINISHED", + "ERR_ATTRIBUTE_WITHOUT_VALUE", + "ERR_ATTRIBUTE_REDEFINED", + "ERR_LITERAL_NOT_STARTED", + "ERR_LITERAL_NOT_FINISHED", + "ERR_COMMENT_NOT_FINISHED", + "ERR_PI_NOT_STARTED", + "ERR_PI_NOT_FINISHED", + "ERR_NOTATION_NOT_STARTED", + "ERR_NOTATION_NOT_FINISHED", + "ERR_ATTLIST_NOT_STARTED", + "ERR_ATTLIST_NOT_FINISHED", + "ERR_MIXED_NOT_STARTED", + "ERR_MIXED_NOT_FINISHED", + "ERR_ELEMCONTENT_NOT_STARTED", + "ERR_ELEMCONTENT_NOT_FINISHED", + "ERR_XMLDECL_NOT_STARTED", + "ERR_XMLDECL_NOT_FINISHED", + "ERR_CONDSEC_NOT_STARTED", + "ERR_CONDSEC_NOT_FINISHED", + "ERR_EXT_SUBSET_NOT_FINISHED", + "ERR_DOCTYPE_NOT_FINISHED", + "ERR_MISPLACED_CDATA_END", + "ERR_CDATA_NOT_FINISHED", + "ERR_RESERVED_XML_NAME", + "ERR_SPACE_REQUIRED", + "ERR_SEPARATOR_REQUIRED", + "ERR_NMTOKEN_REQUIRED", + "ERR_NAME_REQUIRED", + "ERR_PCDATA_REQUIRED", + "ERR_URI_REQUIRED", + "ERR_PUBID_REQUIRED", + "ERR_LT_REQUIRED", + "ERR_GT_REQUIRED", + "ERR_LTSLASH_REQUIRED", + "ERR_EQUAL_REQUIRED", + "ERR_TAG_NAME_MISMATCH", + "ERR_TAG_NOT_FINISHED", + "ERR_STANDALONE_VALUE", + "ERR_ENCODING_NAME", + "ERR_HYPHEN_IN_COMMENT", + "ERR_INVALID_ENCODING", + "ERR_EXT_ENTITY_STANDALONE", + "ERR_CONDSEC_INVALID", + "ERR_VALUE_REQUIRED", + "ERR_NOT_WELL_BALANCED", + "ERR_EXTRA_CONTENT", + "ERR_ENTITY_CHAR_ERROR", + "ERR_ENTITY_PE_INTERNAL", + "ERR_ENTITY_LOOP", + "ERR_ENTITY_BOUNDARY", + "ERR_INVALID_URI", + "ERR_URI_FRAGMENT", + "WAR_CATALOG_PI", + "ERR_NO_DTD", + "ERR_CONDSEC_INVALID_KEYWORD", + "ERR_VERSION_MISSING", + "WAR_UNKNOWN_VERSION", + "WAR_LANG_VALUE", + "WAR_NS_URI", + "WAR_NS_URI_RELATIVE", + "ERR_MISSING_ENCODING", + "NS_ERR_XML_NAMESPACE", + "NS_ERR_UNDEFINED_NAMESPACE", + "NS_ERR_QNAME", + "NS_ERR_ATTRIBUTE_REDEFINED", + "DTD_ATTRIBUTE_DEFAULT", + "DTD_ATTRIBUTE_REDEFINED", + "DTD_ATTRIBUTE_VALUE", + "DTD_CONTENT_ERROR", + "DTD_CONTENT_MODEL", + "DTD_CONTENT_NOT_DETERMINIST", + "DTD_DIFFERENT_PREFIX", + "DTD_ELEM_DEFAULT_NAMESPACE", + "DTD_ELEM_NAMESPACE", + "DTD_ELEM_REDEFINED", + "DTD_EMPTY_NOTATION", + "DTD_ENTITY_TYPE", + "DTD_ID_FIXED", + "DTD_ID_REDEFINED", + "DTD_ID_SUBSET", + "DTD_INVALID_CHILD", + "DTD_INVALID_DEFAULT", + "DTD_LOAD_ERROR", + "DTD_MISSING_ATTRIBUTE", + "DTD_MIXED_CORRUPT", + "DTD_MULTIPLE_ID", + "DTD_NO_DOC", + "DTD_NO_DTD", + "DTD_NO_ELEM_NAME", + "DTD_NO_PREFIX", + "DTD_NO_ROOT", + "DTD_NOTATION_REDEFINED", + "DTD_NOTATION_VALUE", + "DTD_NOT_EMPTY", + "DTD_NOT_PCDATA", + "DTD_NOT_STANDALONE", + "DTD_ROOT_NAME", + "DTD_STANDALONE_WHITE_SPACE", + "DTD_UNKNOWN_ATTRIBUTE", + "DTD_UNKNOWN_ELEM", + "DTD_UNKNOWN_ENTITY", + "DTD_UNKNOWN_ID", + "DTD_UNKNOWN_NOTATION", + "DTD_STANDALONE_DEFAULTED", + "DTD_XMLID_VALUE", + "DTD_XMLID_TYPE", + "HTML_STRUCURE_ERROR", + "HTML_UNKNOWN_TAG", + "RNGP_ANYNAME_ATTR_ANCESTOR", + "RNGP_ATTR_CONFLICT", + "RNGP_ATTRIBUTE_CHILDREN", + "RNGP_ATTRIBUTE_CONTENT", + "RNGP_ATTRIBUTE_EMPTY", + "RNGP_ATTRIBUTE_NOOP", + "RNGP_CHOICE_CONTENT", + "RNGP_CHOICE_EMPTY", + "RNGP_CREATE_FAILURE", + "RNGP_DATA_CONTENT", + "RNGP_DEF_CHOICE_AND_INTERLEAVE", + "RNGP_DEFINE_CREATE_FAILED", + "RNGP_DEFINE_EMPTY", + "RNGP_DEFINE_MISSING", + "RNGP_DEFINE_NAME_MISSING", + "RNGP_ELEM_CONTENT_EMPTY", + "RNGP_ELEM_CONTENT_ERROR", + "RNGP_ELEMENT_EMPTY", + "RNGP_ELEMENT_CONTENT", + "RNGP_ELEMENT_NAME", + "RNGP_ELEMENT_NO_CONTENT", + "RNGP_ELEM_TEXT_CONFLICT", + "RNGP_EMPTY", + "RNGP_EMPTY_CONSTRUCT", + "RNGP_EMPTY_CONTENT", + "RNGP_EMPTY_NOT_EMPTY", + "RNGP_ERROR_TYPE_LIB", + "RNGP_EXCEPT_EMPTY", + "RNGP_EXCEPT_MISSING", + "RNGP_EXCEPT_MULTIPLE", + "RNGP_EXCEPT_NO_CONTENT", + "RNGP_EXTERNALREF_EMTPY", + "RNGP_EXTERNAL_REF_FAILURE", + "RNGP_EXTERNALREF_RECURSE", + "RNGP_FORBIDDEN_ATTRIBUTE", + "RNGP_FOREIGN_ELEMENT", + "RNGP_GRAMMAR_CONTENT", + "RNGP_GRAMMAR_EMPTY", + "RNGP_GRAMMAR_MISSING", + "RNGP_GRAMMAR_NO_START", + "RNGP_GROUP_ATTR_CONFLICT", + "RNGP_HREF_ERROR", + "RNGP_INCLUDE_EMPTY", + "RNGP_INCLUDE_FAILURE", + "RNGP_INCLUDE_RECURSE", + "RNGP_INTERLEAVE_ADD", + "RNGP_INTERLEAVE_CREATE_FAILED", + "RNGP_INTERLEAVE_EMPTY", + "RNGP_INTERLEAVE_NO_CONTENT", + "RNGP_INVALID_DEFINE_NAME", + "RNGP_INVALID_URI", + "RNGP_INVALID_VALUE", + "RNGP_MISSING_HREF", + "RNGP_NAME_MISSING", + "RNGP_NEED_COMBINE", + "RNGP_NOTALLOWED_NOT_EMPTY", + "RNGP_NSNAME_ATTR_ANCESTOR", + "RNGP_NSNAME_NO_NS", + "RNGP_PARAM_FORBIDDEN", + "RNGP_PARAM_NAME_MISSING", + "RNGP_PARENTREF_CREATE_FAILED", + "RNGP_PARENTREF_NAME_INVALID", + "RNGP_PARENTREF_NO_NAME", + "RNGP_PARENTREF_NO_PARENT", + "RNGP_PARENTREF_NOT_EMPTY", + "RNGP_PARSE_ERROR", + "RNGP_PAT_ANYNAME_EXCEPT_ANYNAME", + "RNGP_PAT_ATTR_ATTR", + "RNGP_PAT_ATTR_ELEM", + "RNGP_PAT_DATA_EXCEPT_ATTR", + "RNGP_PAT_DATA_EXCEPT_ELEM", + "RNGP_PAT_DATA_EXCEPT_EMPTY", + "RNGP_PAT_DATA_EXCEPT_GROUP", + "RNGP_PAT_DATA_EXCEPT_INTERLEAVE", + "RNGP_PAT_DATA_EXCEPT_LIST", + "RNGP_PAT_DATA_EXCEPT_ONEMORE", + "RNGP_PAT_DATA_EXCEPT_REF", + "RNGP_PAT_DATA_EXCEPT_TEXT", + "RNGP_PAT_LIST_ATTR", + "RNGP_PAT_LIST_ELEM", + "RNGP_PAT_LIST_INTERLEAVE", + "RNGP_PAT_LIST_LIST", + "RNGP_PAT_LIST_REF", + "RNGP_PAT_LIST_TEXT", + "RNGP_PAT_NSNAME_EXCEPT_ANYNAME", + "RNGP_PAT_NSNAME_EXCEPT_NSNAME", + "RNGP_PAT_ONEMORE_GROUP_ATTR", + "RNGP_PAT_ONEMORE_INTERLEAVE_ATTR", + "RNGP_PAT_START_ATTR", + "RNGP_PAT_START_DATA", + "RNGP_PAT_START_EMPTY", + "RNGP_PAT_START_GROUP", + "RNGP_PAT_START_INTERLEAVE", + "RNGP_PAT_START_LIST", + "RNGP_PAT_START_ONEMORE", + "RNGP_PAT_START_TEXT", + "RNGP_PAT_START_VALUE", + "RNGP_PREFIX_UNDEFINED", + "RNGP_REF_CREATE_FAILED", + "RNGP_REF_CYCLE", + "RNGP_REF_NAME_INVALID", + "RNGP_REF_NO_DEF", + "RNGP_REF_NO_NAME", + "RNGP_REF_NOT_EMPTY", + "RNGP_START_CHOICE_AND_INTERLEAVE", + "RNGP_START_CONTENT", + "RNGP_START_EMPTY", + "RNGP_START_MISSING", + "RNGP_TEXT_EXPECTED", + "RNGP_TEXT_HAS_CHILD", + "RNGP_TYPE_MISSING", + "RNGP_TYPE_NOT_FOUND", + "RNGP_TYPE_VALUE", + "RNGP_UNKNOWN_ATTRIBUTE", + "RNGP_UNKNOWN_COMBINE", + "RNGP_UNKNOWN_CONSTRUCT", + "RNGP_UNKNOWN_TYPE_LIB", + "RNGP_URI_FRAGMENT", + "RNGP_URI_NOT_ABSOLUTE", + "RNGP_VALUE_EMPTY", + "RNGP_VALUE_NO_CONTENT", + "RNGP_XMLNS_NAME", + "RNGP_XML_NS", + "XPATH_EXPRESSION_OK", + "XPATH_NUMBER_ERROR", + "XPATH_UNFINISHED_LITERAL_ERROR", + "XPATH_START_LITERAL_ERROR", + "XPATH_VARIABLE_REF_ERROR", + "XPATH_UNDEF_VARIABLE_ERROR", + "XPATH_INVALID_PREDICATE_ERROR", + "XPATH_EXPR_ERROR", + "XPATH_UNCLOSED_ERROR", + "XPATH_UNKNOWN_FUNC_ERROR", + "XPATH_INVALID_OPERAND", + "XPATH_INVALID_TYPE", + "XPATH_INVALID_ARITY", + "XPATH_INVALID_CTXT_SIZE", + "XPATH_INVALID_CTXT_POSITION", + "XPATH_MEMORY_ERROR", + "XPTR_SYNTAX_ERROR", + "XPTR_RESOURCE_ERROR", + "XPTR_SUB_RESOURCE_ERROR", + "XPATH_UNDEF_PREFIX_ERROR", + "XPATH_ENCODING_ERROR", + "XPATH_INVALID_CHAR_ERROR", + "TREE_INVALID_HEX", + "TREE_INVALID_DEC", + "TREE_UNTERMINATED_ENTITY", + "SAVE_NOT_UTF8", + "SAVE_CHAR_INVALID", + "SAVE_NO_DOCTYPE", + "SAVE_UNKNOWN_ENCODING", + "REGEXP_COMPILE_ERROR", + "IO_UNKNOWN", + "IO_EACCES", + "IO_EAGAIN", + "IO_EBADF", + "IO_EBADMSG", + "IO_EBUSY", + "IO_ECANCELED", + "IO_ECHILD", + "IO_EDEADLK", + "IO_EDOM", + "IO_EEXIST", + "IO_EFAULT", + "IO_EFBIG", + "IO_EINPROGRESS", + "IO_EINTR", + "IO_EINVAL", + "IO_EIO", + "IO_EISDIR", + "IO_EMFILE", + "IO_EMLINK", + "IO_EMSGSIZE", + "IO_ENAMETOOLONG", + "IO_ENFILE", + "IO_ENODEV", + "IO_ENOENT", + "IO_ENOEXEC", + "IO_ENOLCK", + "IO_ENOMEM", + "IO_ENOSPC", + "IO_ENOSYS", + "IO_ENOTDIR", + "IO_ENOTEMPTY", + "IO_ENOTSUP", + "IO_ENOTTY", + "IO_ENXIO", + "IO_EPERM", + "IO_EPIPE", + "IO_ERANGE", + "IO_EROFS", + "IO_ESPIPE", + "IO_ESRCH", + "IO_ETIMEDOUT", + "IO_EXDEV", + "IO_NETWORK_ATTEMPT", + "IO_ENCODER", + "IO_FLUSH", + "IO_WRITE", + "IO_NO_INPUT", + "IO_BUFFER_FULL", + "IO_LOAD_ERROR", + "IO_ENOTSOCK", + "IO_EISCONN", + "IO_ECONNREFUSED", + "IO_ENETUNREACH", + "IO_EADDRINUSE", + "IO_EALREADY", + "IO_EAFNOSUPPORT", + "XINCLUDE_RECURSION", + "XINCLUDE_PARSE_VALUE", + "XINCLUDE_ENTITY_DEF_MISMATCH", + "XINCLUDE_NO_HREF", + "XINCLUDE_NO_FALLBACK", + "XINCLUDE_HREF_URI", + "XINCLUDE_TEXT_FRAGMENT", + "XINCLUDE_TEXT_DOCUMENT", + "XINCLUDE_INVALID_CHAR", + "XINCLUDE_BUILD_FAILED", + "XINCLUDE_UNKNOWN_ENCODING", + "XINCLUDE_MULTIPLE_ROOT", + "XINCLUDE_XPTR_FAILED", + "XINCLUDE_XPTR_RESULT", + "XINCLUDE_INCLUDE_IN_INCLUDE", + "XINCLUDE_FALLBACKS_IN_INCLUDE", + "XINCLUDE_FALLBACK_NOT_IN_INCLUDE", + "XINCLUDE_DEPRECATED_NS", + "XINCLUDE_FRAGMENT_ID", + "CATALOG_MISSING_ATTR", + "CATALOG_ENTRY_BROKEN", + "CATALOG_PREFER_VALUE", + "CATALOG_NOT_CATALOG", + "CATALOG_RECURSION", + "SCHEMAP_PREFIX_UNDEFINED", + "SCHEMAP_ATTRFORMDEFAULT_VALUE", + "SCHEMAP_ATTRGRP_NONAME_NOREF", + "SCHEMAP_ATTR_NONAME_NOREF", + "SCHEMAP_COMPLEXTYPE_NONAME_NOREF", + "SCHEMAP_ELEMFORMDEFAULT_VALUE", + "SCHEMAP_ELEM_NONAME_NOREF", + "SCHEMAP_EXTENSION_NO_BASE", + "SCHEMAP_FACET_NO_VALUE", + "SCHEMAP_FAILED_BUILD_IMPORT", + "SCHEMAP_GROUP_NONAME_NOREF", + "SCHEMAP_IMPORT_NAMESPACE_NOT_URI", + "SCHEMAP_IMPORT_REDEFINE_NSNAME", + "SCHEMAP_IMPORT_SCHEMA_NOT_URI", + "SCHEMAP_INVALID_BOOLEAN", + "SCHEMAP_INVALID_ENUM", + "SCHEMAP_INVALID_FACET", + "SCHEMAP_INVALID_FACET_VALUE", + "SCHEMAP_INVALID_MAXOCCURS", + "SCHEMAP_INVALID_MINOCCURS", + "SCHEMAP_INVALID_REF_AND_SUBTYPE", + "SCHEMAP_INVALID_WHITE_SPACE", + "SCHEMAP_NOATTR_NOREF", + "SCHEMAP_NOTATION_NO_NAME", + "SCHEMAP_NOTYPE_NOREF", + "SCHEMAP_REF_AND_SUBTYPE", + "SCHEMAP_RESTRICTION_NONAME_NOREF", + "SCHEMAP_SIMPLETYPE_NONAME", + "SCHEMAP_TYPE_AND_SUBTYPE", + "SCHEMAP_UNKNOWN_ALL_CHILD", + "SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD", + "SCHEMAP_UNKNOWN_ATTR_CHILD", + "SCHEMAP_UNKNOWN_ATTRGRP_CHILD", + "SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP", + "SCHEMAP_UNKNOWN_BASE_TYPE", + "SCHEMAP_UNKNOWN_CHOICE_CHILD", + "SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD", + "SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD", + "SCHEMAP_UNKNOWN_ELEM_CHILD", + "SCHEMAP_UNKNOWN_EXTENSION_CHILD", + "SCHEMAP_UNKNOWN_FACET_CHILD", + "SCHEMAP_UNKNOWN_FACET_TYPE", + "SCHEMAP_UNKNOWN_GROUP_CHILD", + "SCHEMAP_UNKNOWN_IMPORT_CHILD", + "SCHEMAP_UNKNOWN_LIST_CHILD", + "SCHEMAP_UNKNOWN_NOTATION_CHILD", + "SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD", + "SCHEMAP_UNKNOWN_REF", + "SCHEMAP_UNKNOWN_RESTRICTION_CHILD", + "SCHEMAP_UNKNOWN_SCHEMAS_CHILD", + "SCHEMAP_UNKNOWN_SEQUENCE_CHILD", + "SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD", + "SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD", + "SCHEMAP_UNKNOWN_TYPE", + "SCHEMAP_UNKNOWN_UNION_CHILD", + "SCHEMAP_ELEM_DEFAULT_FIXED", + "SCHEMAP_REGEXP_INVALID", + "SCHEMAP_FAILED_LOAD", + "SCHEMAP_NOTHING_TO_PARSE", + "SCHEMAP_NOROOT", + "SCHEMAP_REDEFINED_GROUP", + "SCHEMAP_REDEFINED_TYPE", + "SCHEMAP_REDEFINED_ELEMENT", + "SCHEMAP_REDEFINED_ATTRGROUP", + "SCHEMAP_REDEFINED_ATTR", + "SCHEMAP_REDEFINED_NOTATION", + "SCHEMAP_FAILED_PARSE", + "SCHEMAP_UNKNOWN_PREFIX", + "SCHEMAP_DEF_AND_PREFIX", + "SCHEMAP_UNKNOWN_INCLUDE_CHILD", + "SCHEMAP_INCLUDE_SCHEMA_NOT_URI", + "SCHEMAP_INCLUDE_SCHEMA_NO_URI", + "SCHEMAP_NOT_SCHEMA", + "SCHEMAP_UNKNOWN_MEMBER_TYPE", + "SCHEMAP_INVALID_ATTR_USE", + "SCHEMAP_RECURSIVE", + "SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE", + "SCHEMAP_INVALID_ATTR_COMBINATION", + "SCHEMAP_INVALID_ATTR_INLINE_COMBINATION", + "SCHEMAP_MISSING_SIMPLETYPE_CHILD", + "SCHEMAP_INVALID_ATTR_NAME", + "SCHEMAP_REF_AND_CONTENT", + "SCHEMAP_CT_PROPS_CORRECT_1", + "SCHEMAP_CT_PROPS_CORRECT_2", + "SCHEMAP_CT_PROPS_CORRECT_3", + "SCHEMAP_CT_PROPS_CORRECT_4", + "SCHEMAP_CT_PROPS_CORRECT_5", + "SCHEMAP_DERIVATION_OK_RESTRICTION_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_3", + "SCHEMAP_WILDCARD_INVALID_NS_MEMBER", + "SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE", + "SCHEMAP_UNION_NOT_EXPRESSIBLE", + "SCHEMAP_SRC_IMPORT_3_1", + "SCHEMAP_SRC_IMPORT_3_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_3", + "SCHEMAP_COS_CT_EXTENDS_1_3", + "SCHEMAV_NOROOT", + "SCHEMAV_UNDECLAREDELEM", + "SCHEMAV_NOTTOPLEVEL", + "SCHEMAV_MISSING", + "SCHEMAV_WRONGELEM", + "SCHEMAV_NOTYPE", + "SCHEMAV_NOROLLBACK", + "SCHEMAV_ISABSTRACT", + "SCHEMAV_NOTEMPTY", + "SCHEMAV_ELEMCONT", + "SCHEMAV_HAVEDEFAULT", + "SCHEMAV_NOTNILLABLE", + "SCHEMAV_EXTRACONTENT", + "SCHEMAV_INVALIDATTR", + "SCHEMAV_INVALIDELEM", + "SCHEMAV_NOTDETERMINIST", + "SCHEMAV_CONSTRUCT", + "SCHEMAV_INTERNAL", + "SCHEMAV_NOTSIMPLE", + "SCHEMAV_ATTRUNKNOWN", + "SCHEMAV_ATTRINVALID", + "SCHEMAV_VALUE", + "SCHEMAV_FACET", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_1", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_2", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_3", + "SCHEMAV_CVC_TYPE_3_1_1", + "SCHEMAV_CVC_TYPE_3_1_2", + "SCHEMAV_CVC_FACET_VALID", + "SCHEMAV_CVC_LENGTH_VALID", + "SCHEMAV_CVC_MINLENGTH_VALID", + "SCHEMAV_CVC_MAXLENGTH_VALID", + "SCHEMAV_CVC_MININCLUSIVE_VALID", + "SCHEMAV_CVC_MAXINCLUSIVE_VALID", + "SCHEMAV_CVC_MINEXCLUSIVE_VALID", + "SCHEMAV_CVC_MAXEXCLUSIVE_VALID", + "SCHEMAV_CVC_TOTALDIGITS_VALID", + "SCHEMAV_CVC_FRACTIONDIGITS_VALID", + "SCHEMAV_CVC_PATTERN_VALID", + "SCHEMAV_CVC_ENUMERATION_VALID", + "SCHEMAV_CVC_COMPLEX_TYPE_2_1", + "SCHEMAV_CVC_COMPLEX_TYPE_2_2", + "SCHEMAV_CVC_COMPLEX_TYPE_2_3", + "SCHEMAV_CVC_COMPLEX_TYPE_2_4", + +#if defined XML_SCHEMAV_CVC_ELT_1 + "SCHEMAV_CVC_ELT_1", + "SCHEMAV_CVC_ELT_2", + "SCHEMAV_CVC_ELT_3_1", + "SCHEMAV_CVC_ELT_3_2_1", + "SCHEMAV_CVC_ELT_3_2_2", + "SCHEMAV_CVC_ELT_4_1", + "SCHEMAV_CVC_ELT_4_2", + "SCHEMAV_CVC_ELT_4_3", + "SCHEMAV_CVC_ELT_5_1_1", + "SCHEMAV_CVC_ELT_5_1_2", + "SCHEMAV_CVC_ELT_5_2_1", + "SCHEMAV_CVC_ELT_5_2_2_1", + "SCHEMAV_CVC_ELT_5_2_2_2_1", + "SCHEMAV_CVC_ELT_5_2_2_2_2", + "SCHEMAV_CVC_ELT_6", + "SCHEMAV_CVC_ELT_7", + "SCHEMAV_CVC_ATTRIBUTE_1", + "SCHEMAV_CVC_ATTRIBUTE_2", + "SCHEMAV_CVC_ATTRIBUTE_3", + "SCHEMAV_CVC_ATTRIBUTE_4", + "SCHEMAV_CVC_COMPLEX_TYPE_3_1", + "SCHEMAV_CVC_COMPLEX_TYPE_3_2_1", + "SCHEMAV_CVC_COMPLEX_TYPE_3_2_2", + "SCHEMAV_CVC_COMPLEX_TYPE_4", + "SCHEMAV_CVC_COMPLEX_TYPE_5_1", + "SCHEMAV_CVC_COMPLEX_TYPE_5_2", + "SCHEMAV_ELEMENT_CONTENT", + "SCHEMAV_DOCUMENT_ELEMENT_MISSING", +#endif + +#if defined XML_SCHEMAV_CVC_COMPLEX_TYPE_1 + "SCHEMAV_CVC_COMPLEX_TYPE_1", + "SCHEMAV_CVC_AU", + "SCHEMAV_CVC_TYPE_1", + "SCHEMAV_CVC_TYPE_2", +#endif + + "XPTR_UNKNOWN_SCHEME", + "XPTR_CHILDSEQ_START", + "XPTR_EVAL_FAILED", + "XPTR_EXTRA_OBJECTS", + "C14N_CREATE_CTXT", + "C14N_REQUIRES_UTF8", + "C14N_CREATE_STACK", + "C14N_INVALID_NODE", + "FTP_PASV_ANSWER", + "FTP_EPSV_ANSWER", + "FTP_ACCNT", + "HTTP_URL_SYNTAX", + "HTTP_USE_IP", + "HTTP_UNKNOWN_HOST", + "SCHEMAP_SRC_SIMPLE_TYPE_1", + "SCHEMAP_SRC_SIMPLE_TYPE_2", + "SCHEMAP_SRC_SIMPLE_TYPE_3", + "SCHEMAP_SRC_SIMPLE_TYPE_4", + "SCHEMAP_SRC_RESOLVE", + "SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE", + "SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE", + "SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES", + "SCHEMAP_ST_PROPS_CORRECT_1", + "SCHEMAP_ST_PROPS_CORRECT_2", + "SCHEMAP_ST_PROPS_CORRECT_3", + "SCHEMAP_COS_ST_RESTRICTS_1_1", + "SCHEMAP_COS_ST_RESTRICTS_1_2", + "SCHEMAP_COS_ST_RESTRICTS_1_3_1", + "SCHEMAP_COS_ST_RESTRICTS_1_3_2", + "SCHEMAP_COS_ST_RESTRICTS_2_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_1_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_1_2", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_2", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_3", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_4", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_5", + "SCHEMAP_COS_ST_RESTRICTS_3_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_1_2", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_2", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_3", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_4", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_5", + "SCHEMAP_COS_ST_DERIVED_OK_2_1", + "SCHEMAP_COS_ST_DERIVED_OK_2_2", + "SCHEMAP_S4S_ELEM_NOT_ALLOWED", + "SCHEMAP_S4S_ELEM_MISSING", + "SCHEMAP_S4S_ATTR_NOT_ALLOWED", + "SCHEMAP_S4S_ATTR_MISSING", + +#if defined XML_SCHEMAP_S4S_ATTR_INVALID_VALUE + "SCHEMAP_S4S_ATTR_INVALID_VALUE", + "SCHEMAP_SRC_ELEMENT_1", + "SCHEMAP_SRC_ELEMENT_2_1", + "SCHEMAP_SRC_ELEMENT_2_2", + "SCHEMAP_SRC_ELEMENT_3", + "SCHEMAP_P_PROPS_CORRECT_1", + "SCHEMAP_P_PROPS_CORRECT_2_1", + "SCHEMAP_P_PROPS_CORRECT_2_2", + "SCHEMAP_E_PROPS_CORRECT_2", + "SCHEMAP_E_PROPS_CORRECT_3", + "SCHEMAP_E_PROPS_CORRECT_4", + "SCHEMAP_E_PROPS_CORRECT_5", + "SCHEMAP_E_PROPS_CORRECT_6", + "SCHEMAP_SRC_INCLUDE", + "SCHEMAP_SRC_ATTRIBUTE_1", + "SCHEMAP_SRC_ATTRIBUTE_2", + "SCHEMAP_SRC_ATTRIBUTE_3_1", + "SCHEMAP_SRC_ATTRIBUTE_3_2", + "SCHEMAP_SRC_ATTRIBUTE_4", + "SCHEMAP_NO_XMLNS", + "SCHEMAP_NO_XSI", + "SCHEMAP_COS_VALID_DEFAULT_1", + "SCHEMAP_COS_VALID_DEFAULT_2_1", + "SCHEMAP_COS_VALID_DEFAULT_2_2_1", + "SCHEMAP_COS_VALID_DEFAULT_2_2_2", + "SCHEMAP_CVC_SIMPLE_TYPE", + "SCHEMAP_COS_CT_EXTENDS_1_1", + "SCHEMAP_SRC_IMPORT_1_1", + "SCHEMAP_SRC_IMPORT_1_2", + "SCHEMAP_SRC_IMPORT_2", + "SCHEMAP_SRC_IMPORT_2_1", + "SCHEMAP_SRC_IMPORT_2_2", +#endif + +#if defined XML_SCHEMAP_INTERNAL + "SCHEMAP_INTERNAL", + "SCHEMAP_NOT_DETERMINISTIC", +#endif + +#if defined XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1 + "SCHEMAP_SRC_ATTRIBUTE_GROUP_1", + "SCHEMAP_SRC_ATTRIBUTE_GROUP_2", + "SCHEMAP_SRC_ATTRIBUTE_GROUP_3", + "SCHEMAP_MG_PROPS_CORRECT_1", + "SCHEMAP_MG_PROPS_CORRECT_2", + "SCHEMAP_SRC_CT_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3", + "SCHEMAP_AU_PROPS_CORRECT_2", + "SCHEMAP_A_PROPS_CORRECT_2", +#endif + NULL +}; + +const char* SaxHandler::errToStr( int errVal ) +{ + const char* str = NULL; + int index = 0; + while ( errVal != xmlErrorVals[index] && xmlErrorVals[index] >= 0 ) + { + index++; + } + + if ( errVal == xmlErrorVals[index] ) + { + str = xmlErrorStrs[index]; + } + + return str; +} + + +int SaxHandler::parseMemory( const char* buffer, int size ) +{ + int result = xmlSAXUserParseMemory( &sax, + this, + buffer, + size ); + return result; +} + +int SaxHandler::parseFile( const char* filename ) +{ + int result = xmlSAXUserParseFile( &sax, + this, + filename ); + return result; +} + +void SaxHandler::startDocument(void *user_data) +{ + SaxHandler* self = reinterpret_cast<SaxHandler*>(user_data); + self->_startDocument(); +} + +void SaxHandler::endDocument(void *user_data) +{ + SaxHandler* self = reinterpret_cast<SaxHandler*>(user_data); + self->_endDocument(); +} +void SaxHandler::startElement(void *user_data, + const xmlChar *name, + const xmlChar **attrs) +{ + SaxHandler* self = reinterpret_cast<SaxHandler*>(user_data); + self->_startElement(name, attrs); +} +void SaxHandler::endElement(void *user_data, + const xmlChar *name) +{ + SaxHandler* self = reinterpret_cast<SaxHandler*>(user_data); + self->_endElement(name); +} +void SaxHandler::characters(void *user_data, + const xmlChar *ch, + int len) +{ + SaxHandler* self = reinterpret_cast<SaxHandler*>(user_data); + self->_characters(ch, len); +} + + + + + + + +FlatSaxHandler::FlatSaxHandler() + : SaxHandler() +{ +} + +FlatSaxHandler::~FlatSaxHandler() +{ +} + +void FlatSaxHandler::_startElement(const xmlChar *name, const xmlChar **attrs) +{ + data.clear(); +} + +void FlatSaxHandler::_endElement(const xmlChar *name) +{ + //g_message("<%s>%s</%s>", name, data.c_str(), name); + data.clear(); +} + +void FlatSaxHandler::_characters(const xmlChar *ch, int len) +{ + data.append((const char*)ch, len); +} + + +} // namespace IO +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/io/simple-sax.h b/src/io/simple-sax.h new file mode 100644 index 000000000..7de816a14 --- /dev/null +++ b/src/io/simple-sax.h @@ -0,0 +1,97 @@ +#ifndef SEEN_SIMPLE_SAX_H +#define SEEN_SIMPLE_SAX_H + +/* + * SimpleSAX + * + * Authors: + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2004 AUTHORS + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <libxml/parser.h> +#include <glibmm/ustring.h> + +namespace Inkscape { +namespace IO +{ + +class SaxHandler +{ +public: + SaxHandler(); + virtual ~SaxHandler(); + + int parseMemory( const char* buffer, int size ); + int parseFile( const char* filename ); + + static const char* errToStr( int errVal ); + +protected: + virtual void _startDocument() {} + virtual void _endDocument() {} + virtual void _startElement(const xmlChar *name, const xmlChar **attrs) {} + virtual void _endElement(const xmlChar *name) {} + virtual void _characters(const xmlChar *ch, int len) {} + +private: + static void startDocument(void *user_data); + static void endDocument(void *user_data); + static void startElement(void *user_data, + const xmlChar *name, + const xmlChar **attrs); + static void endElement(void *user_data, + const xmlChar *name); + static void characters(void * user_data, + const xmlChar *ch, + int len); + + // Disable: + SaxHandler(SaxHandler const &); + SaxHandler &operator=(SaxHandler const &); + + xmlSAXHandler sax; +}; + + + +class FlatSaxHandler : public SaxHandler +{ +public: + FlatSaxHandler(); + virtual ~FlatSaxHandler(); + +protected: + virtual void _startElement(const xmlChar *name, const xmlChar **attrs); + virtual void _endElement(const xmlChar *name); + virtual void _characters(const xmlChar *ch, int len); + + Glib::ustring data; + +private: + // Disable: + FlatSaxHandler(FlatSaxHandler const &); + FlatSaxHandler &operator=(FlatSaxHandler const &); +}; + + + +} // namespace IO +} // namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + +#endif // SEEN_SIMPLE_SAX_H diff --git a/src/io/streamtest.cpp b/src/io/streamtest.cpp new file mode 100644 index 000000000..b25ef43f0 --- /dev/null +++ b/src/io/streamtest.cpp @@ -0,0 +1,244 @@ + + +#include <stdio.h> +#include <limits.h> // realpath +#include <stdlib.h> // mkdtemp, realpath +#include <unistd.h> // chdir +#include <string.h> // strlen, strncpy, strrchr + +#include "inkscapestream.h" +#include "base64stream.h" +#include "gzipstream.h" +#include "stringstream.h" +#include "uristream.h" +#include "xsltstream.h" + +// quick way to pass the name of the executable into the test +char myself[PATH_MAX]; + +// names and path storage for other tests +char *xmlname = "crystalegg.xml"; +char xmlpath[PATH_MAX]; +char *xslname = "doc2html.xsl"; +char xslpath[PATH_MAX]; + +bool testUriStream() +{ + printf("######### UriStream copy ############\n"); + Inkscape::URI inUri(myself); + Inkscape::IO::UriInputStream ins(inUri); + Inkscape::URI outUri("streamtest.copy"); + Inkscape::IO::UriOutputStream outs(outUri); + + pipeStream(ins, outs); + + ins.close(); + outs.close(); + + return true; +} + +bool testWriter() +{ + printf("######### OutputStreamWriter ############\n"); + Inkscape::IO::StdOutputStream outs; + Inkscape::IO::OutputStreamWriter writer(outs); + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testStdWriter() +{ + printf("######### StdWriter ############\n"); + Inkscape::IO::StdWriter writer; + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testBase64() +{ + printf("######### Base64 Out ############\n"); + Inkscape::URI plainInUri(xmlpath); + Inkscape::IO::UriInputStream ins1(plainInUri); + + Inkscape::URI b64OutUri("crystalegg.xml.b64"); + Inkscape::IO::UriOutputStream outs1(b64OutUri); + Inkscape::IO::Base64OutputStream b64Outs(outs1); + + pipeStream(ins1, b64Outs); + + ins1.close(); + b64Outs.close(); + + printf("######### Base64 In ############\n"); + Inkscape::URI b64InUri("crystalegg.xml.b64"); + Inkscape::IO::UriInputStream ins2(b64InUri); + Inkscape::IO::Base64InputStream b64Ins(ins2); + + Inkscape::URI plainOutUri("crystalegg.xml.b64dec"); + Inkscape::IO::UriOutputStream outs2(plainOutUri); + + pipeStream(b64Ins, outs2); + + outs2.close(); + b64Ins.close(); + + return true; +} + +bool testXslt() +{ + printf("######### XSLT Sheet ############\n"); + Inkscape::URI xsltSheetUri(xslpath); + Inkscape::IO::UriInputStream xsltSheetIns(xsltSheetUri); + Inkscape::IO::XsltStyleSheet stylesheet(xsltSheetIns); + xsltSheetIns.close(); + + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream xmlIns(sourceUri); + + printf("######### XSLT Input ############\n"); + Inkscape::URI destUri("test.html"); + Inkscape::IO::UriOutputStream xmlOuts(destUri); + + Inkscape::IO::XsltInputStream xsltIns(xmlIns, stylesheet); + pipeStream(xsltIns, xmlOuts); + xsltIns.close(); + xmlOuts.close(); + + + printf("######### XSLT Output ############\n"); + + Inkscape::IO::UriInputStream xmlIns2(sourceUri); + + Inkscape::URI destUri2("test2.html"); + Inkscape::IO::UriOutputStream xmlOuts2(destUri2); + + Inkscape::IO::XsltOutputStream xsltOuts(xmlOuts2, stylesheet); + pipeStream(xmlIns2, xsltOuts); + xmlIns2.close(); + xsltOuts.close(); + + return true; +} + +bool testGzip() +{ + + printf("######### Gzip Output ############\n"); + Inkscape::URI gzUri("test.gz"); + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream sourceIns(sourceUri); + Inkscape::IO::UriOutputStream gzOuts(gzUri); + + Inkscape::IO::GzipOutputStream gzipOuts(gzOuts); + pipeStream(sourceIns, gzipOuts); + sourceIns.close(); + gzipOuts.close(); + + printf("######### Gzip Input ############\n"); + + Inkscape::IO::UriInputStream gzIns(gzUri); + Inkscape::URI destUri("crystalegg2.xml"); + Inkscape::IO::UriOutputStream destOuts(destUri); + + Inkscape::IO::GzipInputStream gzipIns(gzIns); + pipeStream(gzipIns, destOuts); + gzipIns.close(); + destOuts.close(); + + return true; +} + +bool doTest() +{ + if (!testUriStream()) + { + return false; + } + if (!testWriter()) + { + return false; + } + if (!testStdWriter()) + { + return false; + } + if (!testBase64()) + { + return false; + } + if (!testXslt()) + { + return false; + } + if (!testGzip()) + { + return false; + } + return true; +} + +void path_init(char *path, char *name) +{ + if (strlen(name)>PATH_MAX-strlen(myself)) + { + printf("merging paths would be too long\n"); + exit(1); + } + strncpy(path,myself,PATH_MAX); + char * ptr = strrchr(path,'/'); + if (!ptr) + { + printf("path '%s' is missing any slashes\n",path); + exit(1); + } + strncpy(ptr+1,name,strlen(name)+1); + printf("'%s'\n",path); +} + + +int main(int argc, char **argv) +{ + if (!realpath(argv[0],myself)) + { + perror("realpath"); + return 1; + } + path_init(xmlpath,xmlname); + path_init(xslpath,xslname); + + // create temp files somewhere else instead of current dir + // TODO: clean them up too + char * testpath = strdup("/tmp/streamtest-XXXXXX"); + testpath = mkdtemp(testpath); + if (!testpath) + { + perror("mkdtemp"); + return 1; + } + if (chdir(testpath)) + { + perror("chdir"); + return 1; + } + + if (!doTest()) + { + printf("#### Test failed\n"); + return 1; + } + else + { + printf("##### Test succeeded\n"); + } + return 0; +} diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp new file mode 100644 index 000000000..45fb6fe30 --- /dev/null +++ b/src/io/stringstream.cpp @@ -0,0 +1,128 @@ +/** + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "stringstream.h" + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +StringInputStream::StringInputStream(Glib::ustring &sourceString) + : buffer(sourceString) +{ + position = 0; +} + +/** + * + */ +StringInputStream::~StringInputStream() +{ + +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int StringInputStream::available() +{ + return buffer.size() - position; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void StringInputStream::close() +{ +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int StringInputStream::get() +{ + if (position >= (int)buffer.size()) + return -1; + int ch = (int) buffer[position++]; + return ch; +} + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +StringOutputStream::StringOutputStream() +{ +} + +/** + * + */ +StringOutputStream::~StringOutputStream() +{ +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void StringOutputStream::close() +{ +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void StringOutputStream::flush() +{ + //nothing to do +} + +/** + * Writes the specified byte to this output stream. + */ +void StringOutputStream::put(int ch) +{ + gunichar uch = (gunichar)ch; + buffer.push_back(uch); +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/stringstream.h b/src/io/stringstream.h new file mode 100644 index 000000000..4a05d88a9 --- /dev/null +++ b/src/io/stringstream.h @@ -0,0 +1,96 @@ +#ifndef __INKSCAPE_IO_STRINGSTREAM_H__ +#define __INKSCAPE_IO_STRINGSTREAM_H__ + +#include <glibmm.h> + +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + +/** + * This class is for reading character from a Glib::ustring + * + */ +class StringInputStream : public InputStream +{ + +public: + + StringInputStream(Glib::ustring &sourceString); + + virtual ~StringInputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + Glib::ustring &buffer; + + long position; + +}; // class StringInputStream + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for sending a stream to a Glib::ustring + * + */ +class StringOutputStream : public OutputStream +{ + +public: + + StringOutputStream(); + + virtual ~StringOutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + + virtual Glib::ustring &getString() + { return buffer; } + + virtual void clear() + { buffer = ""; } + +private: + + Glib::ustring buffer; + + +}; // class StringOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + + +#endif /* __INKSCAPE_IO_STRINGSTREAM_H__ */ diff --git a/src/io/sys.cpp b/src/io/sys.cpp new file mode 100644 index 000000000..89afe9fb4 --- /dev/null +++ b/src/io/sys.cpp @@ -0,0 +1,300 @@ + +/* + * System abstraction utility routines + * + * Authors: + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib/gutils.h> +#if GLIB_CHECK_VERSION(2,6,0) + #include <glib/gstdio.h> +#endif +#include <glibmm/ustring.h> +#include <gtk/gtkmessagedialog.h> + +#include "prefs-utils.h" +#include "sys.h" + +#ifdef WIN32 + +// For now to get at is_os_wide(). +#include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; + +#endif + +//#define INK_DUMP_FILENAME_CONV 1 +#undef INK_DUMP_FILENAME_CONV + +//#define INK_DUMP_FOPEN 1 +#undef INK_DUMP_FOPEN + +void dump_str(gchar const *str, gchar const *prefix); +void dump_ustr(Glib::ustring const &ustr); + +extern guint update_in_progress; + + +#define DEBUG_MESSAGE(key, ...) \ +{\ + gint dump = prefs_get_int_attribute_limited("options.bulia", #key, 0, 0, 1);\ + gint dumpD = prefs_get_int_attribute_limited("options.bulia", #key"D", 0, 0, 1);\ + gint dumpD2 = prefs_get_int_attribute_limited("options.bulia", #key"D2", 0, 0, 1);\ + dumpD &= ( (update_in_progress == 0) || dumpD2 );\ + if ( dump )\ + {\ + g_message( __VA_ARGS__ );\ +\ + }\ + if ( dumpD )\ + {\ + GtkWidget *dialog = gtk_message_dialog_new(NULL,\ + GTK_DIALOG_DESTROY_WITH_PARENT, \ + GTK_MESSAGE_INFO, \ + GTK_BUTTONS_OK, \ + __VA_ARGS__ \ + );\ + g_signal_connect_swapped(dialog, "response",\ + G_CALLBACK(gtk_widget_destroy), \ + dialog); \ + gtk_widget_show_all( dialog );\ + }\ +} + + + + +void Inkscape::IO::dump_fopen_call( char const *utf8name, char const *id ) +{ +#ifdef INK_DUMP_FOPEN + Glib::ustring str; + for ( int i = 0; utf8name[i]; i++ ) + { + if ( utf8name[i] == '\\' ) + { + str += "\\\\"; + } + else if ( (utf8name[i] >= 0x20) && ((0x0ff & utf8name[i]) <= 0x7f) ) + { + str += utf8name[i]; + } + else + { + gchar tmp[32]; + g_snprintf( tmp, sizeof(tmp), "\\x%02x", (0x0ff & utf8name[i]) ); + str += tmp; + } + } + g_message( "fopen call %s for [%s]", id, str.data() ); +#endif +} + +FILE *Inkscape::IO::fopen_utf8name( char const *utf8name, char const *mode ) +{ + static gint counter = 0; + FILE* fp = NULL; + + DEBUG_MESSAGE( dumpOne, "entering fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + +#ifndef WIN32 + DEBUG_MESSAGE( dumpOne, " STEP 0 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) + { + DEBUG_MESSAGE( dumpOne, " STEP 1 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + fp = std::fopen(filename, mode); + DEBUG_MESSAGE( dumpOne, " STEP 2 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + g_free(filename); + DEBUG_MESSAGE( dumpOne, " STEP 3 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + filename = 0; + } +#else + Glib::ustring how( mode ); + how.append("b"); + DEBUG_MESSAGE( dumpOne, " calling is_os_wide() ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + + fp = g_fopen(utf8name, how.c_str()); +#endif + + DEBUG_MESSAGE( dumpOne, "leaving fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + + return fp; +} + + +int Inkscape::IO::mkdir_utf8name( char const *utf8name ) +{ + static gint counter = 0; + int retval = -1; + + DEBUG_MESSAGE( dumpMk, "entering mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) ); + +#ifndef WIN32 + DEBUG_MESSAGE( dumpMk, " STEP 0 ( '%s' )[%d]", utf8name, (counter++) ); + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) + { + DEBUG_MESSAGE( dumpMk, " STEP 1 ( '%s' )[%d]", utf8name, (counter++) ); + retval = ::mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); + DEBUG_MESSAGE( dumpMk, " STEP 2 ( '%s' )[%d]", utf8name, (counter++) ); + g_free(filename); + DEBUG_MESSAGE( dumpMk, " STEP 3 ( '%s' )[%d]", utf8name, (counter++) ); + filename = 0; + } +#else + DEBUG_MESSAGE( dumpMk, " calling is_os_wide() ( '%s' )[%d]", utf8name, (counter++) ); + + // Mode should be ingnored inside of glib on the way in + retval = g_mkdir( utf8name, 0 ); +#endif + + DEBUG_MESSAGE( dumpMk, "leaving mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) ); + + return retval; +} + +bool Inkscape::IO::file_test( char const *utf8name, GFileTest test ) +{ + bool exists = false; + + if ( utf8name ) { + gchar *filename = NULL; + if (utf8name && !g_utf8_validate(utf8name, -1, NULL)) { + /* FIXME: Trying to guess whether or not a filename is already in utf8 is unreliable. + If any callers pass non-utf8 data (e.g. using g_get_home_dir), then change caller to + use simple g_file_test. Then add g_return_val_if_fail(g_utf_validate(...), false) + to beginning of this function. */ + filename = g_strdup(utf8name); + // Looks like g_get_home_dir isn't safe. + //g_warning("invalid UTF-8 detected internally. HUNT IT DOWN AND KILL IT!!!"); + } else { + filename = g_filename_from_utf8 ( utf8name, -1, NULL, NULL, NULL ); + } + if ( filename ) { + exists = g_file_test (filename, test); + g_free(filename); + filename = NULL; + } else { + g_warning( "Unable to convert filename in IO:file_test" ); + } + } + + return exists; +} + +/** Wrapper around g_dir_open, but taking a utf8name as first argument. */ +GDir * +Inkscape::IO::dir_open(gchar const *const utf8name, guint const flags, GError **const error) +{ + gchar *const opsys_name = g_filename_from_utf8(utf8name, -1, NULL, NULL, error); + if (opsys_name) { + GDir *ret = g_dir_open(opsys_name, flags, error); + g_free(opsys_name); + return ret; + } else { + return NULL; + } +} + +/** + * Like g_dir_read_name, but returns a utf8name (which must be freed, unlike g_dir_read_name). + * + * N.B. Skips over any dir entries that fail to convert to utf8. + */ +gchar * +Inkscape::IO::dir_read_utf8name(GDir *dir) +{ + for (;;) { + gchar const *const opsys_name = g_dir_read_name(dir); + if (!opsys_name) { + return NULL; + } + gchar *utf8_name = g_filename_to_utf8(opsys_name, -1, NULL, NULL, NULL); + if (utf8_name) { + return utf8_name; + } + } +} + + +gchar* Inkscape::IO::locale_to_utf8_fallback( const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error ) +{ + gchar *result = NULL; + if ( opsysstring ) { + gchar *newFileName = g_locale_to_utf8( opsysstring, len, bytes_read, bytes_written, error ); + if ( newFileName ) { + if ( !g_utf8_validate(newFileName, -1, NULL) ) { + g_warning( "input filename did not yield UTF-8" ); + g_free( newFileName ); + } else { + result = newFileName; + } + newFileName = 0; + } else if ( g_utf8_validate(opsysstring, -1, NULL) ) { + // This *might* be a case that we want + // g_warning( "input failed filename->utf8, fell back to original" ); + // TODO handle cases when len >= 0 + result = g_strdup( opsysstring ); + } else { + gchar const *charset = 0; + g_get_charset(&charset); + g_warning( "input filename conversion failed for file with locale charset '%s'", charset ); + } + } + return result; +} + + +gchar* Inkscape::IO::sanitizeString( gchar const * str ) +{ + gchar *result = NULL; + if ( str ) { + if ( g_utf8_validate(str, -1, NULL) ) { + result = g_strdup(str); + } else { + guchar scratch[8]; + Glib::ustring buf; + guchar const *ptr = (guchar const*)str; + while ( *ptr ) + { + if ( *ptr == '\\' ) + { + buf.append("\\\\"); + } else if ( *ptr < 0x80 ) { + buf += (char)(*ptr); + } else { + g_snprintf((gchar*)scratch, sizeof(scratch), "\\x%02x", *ptr); + buf.append((const char*)scratch); + } + ptr++; + } + result = g_strdup(buf.c_str()); + } + } + return result; +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/io/sys.h b/src/io/sys.h new file mode 100644 index 000000000..29c0ad96a --- /dev/null +++ b/src/io/sys.h @@ -0,0 +1,51 @@ +#ifndef SEEN_SYS_H +#define SEEN_SYS_H + +/* + * System abstraction utility routines + * + * Authors: + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <stdio.h> +#include <glib/gtypes.h> +#include <glib/gdir.h> +#include <glib/gfileutils.h> + +/*##################### +## U T I L I T Y +#####################*/ + +namespace Inkscape { +namespace IO { + +void dump_fopen_call( char const *utf8name, char const *id ); + +FILE *fopen_utf8name( char const *utf8name, char const *mode ); + +int mkdir_utf8name( char const *utf8name ); + +bool file_test( char const *utf8name, GFileTest test ); + +GDir *dir_open(gchar const *utf8name, guint flags, GError **error); + +gchar *dir_read_utf8name(GDir *dir); + +gchar* locale_to_utf8_fallback( const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error ); + +gchar* sanitizeString( gchar const * str ); + +} +} + + +#endif // SEEN_SYS_H diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp new file mode 100644 index 000000000..e06498d52 --- /dev/null +++ b/src/io/uristream.cpp @@ -0,0 +1,499 @@ +/** + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "uristream.h" +#include "sys.h" + +#ifdef WIN32 +// For now to get at is_os_wide(). +# include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; +#endif + + +namespace Inkscape +{ +namespace IO +{ + +/* + * URI scheme types + */ +#define SCHEME_NONE 0 +#define SCHEME_FILE 1 +#define SCHEME_DATA 2 + +/* + * A temporary modification of Jon Cruz's portable fopen(). + * Simplified a bit, since we will always use binary +*/ + +#define FILE_READ 1 +#define FILE_WRITE 2 + +static FILE *fopen_utf8name( char const *utf8name, int mode ) +{ + FILE *fp = NULL; + if (!utf8name) + { + return NULL; + } + if (mode!=FILE_READ && mode!=FILE_WRITE) + { + return NULL; + } + +#ifndef WIN32 + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) { + if (mode == FILE_READ) + fp = std::fopen(filename, "rb"); + else + fp = std::fopen(filename, "wb"); + g_free(filename); + } +#else + if ( PrintWin32::is_os_wide() ) { + gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL ); + if ( wideName ) { + if (mode == FILE_READ) + fp = _wfopen( (wchar_t*)wideName, L"rb" ); + else + fp = _wfopen( (wchar_t*)wideName, L"wb" ); + g_free( wideName ); + } else { + gchar *safe = Inkscape::IO::sanitizeString(utf8name); + g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe); + g_free(safe); + } + } else { + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) { + if (mode == FILE_READ) + fp = std::fopen(filename, "rb"); + else + fp = std::fopen(filename, "wb"); + g_free(filename); + } + } +#endif + + return fp; +} + + + +//######################################################################### +//# U R I I N P U T S T R E A M / R E A D E R +//######################################################################### + + +/** + * + */ +UriInputStream::UriInputStream(Inkscape::URI &source) + throw (StreamException): uri(source) +{ + //get information from uri + char *schemestr = (char *) uri.getScheme(); + scheme = SCHEME_FILE; + if (!schemestr || strncmp("file", schemestr, 4)==0) + scheme = SCHEME_FILE; + else if (strncmp("data", schemestr, 4)==0) + scheme = SCHEME_DATA; + //printf("in schemestr:'%s' scheme:'%d'\n", schemestr, scheme); + char *cpath = NULL; + + switch (scheme) { + + case SCHEME_FILE: + cpath = (char *) uri.toNativeFilename(); + //printf("in cpath:'%s'\n", cpath); + inf = fopen_utf8name(cpath, FILE_READ); + //inf = fopen(cpath, "rb"); + g_free(cpath); + if (!inf) { + Glib::ustring err = "UriInputStream cannot open file "; + err += cpath; + throw StreamException(err); + } + break; + + case SCHEME_DATA: + data = (unsigned char *) uri.getPath(); + //printf("in data:'%s'\n", data); + dataPos = 0; + dataLen = strlen((const char *)data); + break; + + } + closed = false; +} + +/** + * + */ +UriInputStream::UriInputStream(FILE *source, Inkscape::URI &uri) + throw (StreamException): inf(source), + uri(uri) +{ + scheme = SCHEME_FILE; + if (!inf) { + Glib::ustring err = "UriInputStream passed NULL"; + throw StreamException(err); + } + closed = false; +} + +/** + * + */ +UriInputStream::~UriInputStream() throw(StreamException) +{ + close(); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int UriInputStream::available() throw(StreamException) +{ + return 0; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void UriInputStream::close() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!inf) + return; + fflush(inf); + fclose(inf); + inf=NULL; + break; + + case SCHEME_DATA: + //do nothing + break; + + }//switch + + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int UriInputStream::get() throw(StreamException) +{ + int retVal = -1; + if (!closed) + { + switch (scheme) { + + case SCHEME_FILE: + if (!inf || feof(inf)) + { + retVal = -1; + } + else + { + retVal = fgetc(inf); + } + break; + + case SCHEME_DATA: + if (dataPos >= dataLen) + { + retVal = -1; + } + else + { + retVal = data[dataPos++]; + } + break; + }//switch + } + return retVal; +} + + + + + + +/** + * + */ +UriReader::UriReader(Inkscape::URI &uri) + throw (StreamException) +{ + inputStream = new UriInputStream(uri); +} + +/** + * + */ +UriReader::~UriReader() throw (StreamException) +{ + delete inputStream; +} + +/** + * + */ +int UriReader::available() throw(StreamException) +{ + return inputStream->available(); +} + +/** + * + */ +void UriReader::close() throw(StreamException) +{ + inputStream->close(); +} + +/** + * + */ +gunichar UriReader::get() throw(StreamException) +{ + gunichar ch = (gunichar)inputStream->get(); + return ch; +} + + +//######################################################################### +//# U R I O U T P U T S T R E A M / W R I T E R +//######################################################################### + +/** + * Temporary kludge + */ +UriOutputStream::UriOutputStream(FILE* fp, Inkscape::URI &destination) + throw (StreamException): closed(false), + ownsFile(false), + outf(fp), + uri(destination), + scheme(SCHEME_FILE) +{ + if (!outf) { + Glib::ustring err = "UriOutputStream given null file "; + throw StreamException(err); + } +} + +/** + * + */ +UriOutputStream::UriOutputStream(Inkscape::URI &destination) + throw (StreamException): closed(false), + ownsFile(true), + outf(NULL), + uri(destination), + scheme(SCHEME_FILE) +{ + //get information from uri + char *schemestr = (char *) uri.getScheme(); + if (!schemestr || strncmp("file", schemestr, 4)==0) + scheme = SCHEME_FILE; + else if (strncmp("data", schemestr, 4)==0) + scheme = SCHEME_DATA; + //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme); + char *cpath = NULL; + + switch (scheme) { + + case SCHEME_FILE: + cpath = (char *) uri.toNativeFilename(); + //printf("out path:'%s'\n", cpath); + outf = fopen_utf8name(cpath, FILE_WRITE); + //outf = fopen(cpath, "wb"); + g_free(cpath); + if (!outf) { + Glib::ustring err = "UriOutputStream cannot open file "; + err += cpath; + throw StreamException(err); + } + break; + + case SCHEME_DATA: + data = "data:"; + break; + + }//switch +} + + +/** + * + */ +UriOutputStream::~UriOutputStream() throw(StreamException) +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void UriOutputStream::close() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + fflush(outf); + if ( ownsFile ) + fclose(outf); + outf=NULL; + break; + + case SCHEME_DATA: + uri = URI(data.raw().c_str()); + break; + + }//switch + + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void UriOutputStream::flush() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + fflush(outf); + break; + + case SCHEME_DATA: + //nothing + break; + + }//switch + +} + +/** + * Writes the specified byte to this output stream. + */ +void UriOutputStream::put(int ch) throw(StreamException) +{ + if (closed) + return; + + unsigned char uch; + gunichar gch; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + uch = (unsigned char)(ch & 0xff); + fputc(uch, outf); + //fwrite(uch, 1, 1, outf); + break; + + case SCHEME_DATA: + gch = (gunichar) ch; + data.push_back(gch); + break; + + }//switch + +} + + + + + +/** + * + */ +UriWriter::UriWriter(Inkscape::URI &uri) + throw (StreamException) +{ + outputStream = new UriOutputStream(uri); +} + +/** + * + */ +UriWriter::~UriWriter() throw (StreamException) +{ + delete outputStream; +} + +/** + * + */ +void UriWriter::close() throw(StreamException) +{ + outputStream->close(); +} + +/** + * + */ +void UriWriter::flush() throw(StreamException) +{ + outputStream->flush(); +} + +/** + * + */ +void UriWriter::put(gunichar ch) throw(StreamException) +{ + int ich = (int)ch; + outputStream->put(ich); +} + + + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/uristream.h b/src/io/uristream.h new file mode 100644 index 000000000..d62065976 --- /dev/null +++ b/src/io/uristream.h @@ -0,0 +1,173 @@ +#ifndef __INKSCAPE_IO_URISTREAM_H__ +#define __INKSCAPE_IO_URISTREAM_H__ +/** + * This should be the only way that we provide sources/sinks + * to any input/output stream. + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include <uri.h> + +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# U R I I N P U T S T R E A M / R E A D E R +//######################################################################### + +/** + * This class is for receiving a stream of data from a resource + * defined in a URI + */ +class UriInputStream : public InputStream +{ + +public: + UriInputStream(FILE *source, Inkscape::URI &uri) throw(StreamException); + + UriInputStream(Inkscape::URI &source) throw(StreamException); + + virtual ~UriInputStream() throw(StreamException); + + virtual int available() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual int get() throw(StreamException); + +private: + + bool closed; + + FILE *inf; //for file: uris + unsigned char *data; //for data: uris + int dataPos; // current read position in data field + int dataLen; // length of data buffer + + Inkscape::URI &uri; + + int scheme; + +}; // class UriInputStream + + + + +/** + * This class is for receiving a stream of formatted data from a resource + * defined in a URI + */ +class UriReader : public BasicReader +{ + +public: + + UriReader(Inkscape::URI &source) throw(StreamException); + + virtual ~UriReader() throw(StreamException); + + virtual int available() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual gunichar get() throw(StreamException); + +private: + + UriInputStream *inputStream; + +}; // class UriReader + + + +//######################################################################### +//# U R I O U T P U T S T R E A M / W R I T E R +//######################################################################### + +/** + * This class is for sending a stream to a destination resource + * defined in a URI + * + */ +class UriOutputStream : public OutputStream +{ + +public: + + UriOutputStream(FILE *fp, Inkscape::URI &destination) throw(StreamException); + + UriOutputStream(Inkscape::URI &destination) throw(StreamException); + + virtual ~UriOutputStream() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual void flush() throw(StreamException); + + virtual void put(int ch) throw(StreamException); + +private: + + bool closed; + bool ownsFile; + + FILE *outf; //for file: uris + Glib::ustring data; //for data: uris + + Inkscape::URI &uri; + + int scheme; + +}; // class UriOutputStream + + + + + +/** + * This class is for sending a stream of formatted data to a resource + * defined in a URI + */ +class UriWriter : public BasicWriter +{ + +public: + + UriWriter(Inkscape::URI &source) throw(StreamException); + + virtual ~UriWriter() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual void flush() throw(StreamException); + + virtual void put(gunichar ch) throw(StreamException); + +private: + + UriOutputStream *outputStream; + +}; // class UriReader + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_URISTREAM_H__ */ diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp new file mode 100644 index 000000000..71619a51e --- /dev/null +++ b/src/io/xsltstream.cpp @@ -0,0 +1,220 @@ +/** + * XSL Transforming input and output classes + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "xsltstream.h" +#include "stringstream.h" +#include <libxslt/transform.h> + + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### +/** + * + */ +XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) throw (StreamException) +{ + StringOutputStream outs; + pipeStream(xsltSource, outs); + std::string strBuf = outs.getString().raw(); + xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + stylesheet = xsltParseStylesheetDoc(doc); + //xmlFreeDoc(doc); +} + +/** + * + */ +XsltStyleSheet::~XsltStyleSheet() +{ + xsltFreeStylesheet(stylesheet); +} + + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet) + throw (StreamException) + : BasicInputStream(xmlSource), stylesheet(sheet) +{ + //Load the data + StringOutputStream outs; + pipeStream(source, outs); + std::string strBuf = outs.getString().raw(); + + //Do the processing + const char *params[1]; + params[0] = NULL; + xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1); + outpos = 0; + + //Free our mem + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); +} + +/** + * + */ +XsltInputStream::~XsltInputStream() throw (StreamException) +{ + xmlFree(outbuf); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int XsltInputStream::available() throw (StreamException) +{ + return outsize - outpos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void XsltInputStream::close() throw (StreamException) +{ + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int XsltInputStream::get() throw (StreamException) +{ + if (closed) + return -1; + if (outpos >= outsize) + return -1; + int ch = (int) outbuf[outpos++]; + return ch; +} + + + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet) + throw (StreamException) + : BasicOutputStream(dest), stylesheet(sheet) +{ + flushed = false; +} + +/** + * + */ +XsltOutputStream::~XsltOutputStream() throw (StreamException) +{ + //do not automatically close +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void XsltOutputStream::close() throw (StreamException) +{ + flush(); + destination.close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void XsltOutputStream::flush() throw (StreamException) +{ + if (flushed) + { + destination.flush(); + return; + } + + //Do the processing + xmlChar *resbuf; + int resSize; + const char *params[1]; + params[0] = NULL; + xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1); + /* + xmlErrorPtr err = xmlGetLastError(); + if (err) + { + throw StreamException(err->message); + } + */ + + for (int i=0 ; i<resSize ; i++) + { + char ch = resbuf[i]; + destination.put(ch); + } + + //Free our mem + xmlFree(resbuf); + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); + destination.flush(); + flushed = true; +} + +/** + * Writes the specified byte to this output stream. + */ +void XsltOutputStream::put(int ch) throw (StreamException) +{ + gunichar uch = (gunichar) ch; + outbuf.push_back(uch); +} + + + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/xsltstream.h b/src/io/xsltstream.h new file mode 100644 index 000000000..5e293abc6 --- /dev/null +++ b/src/io/xsltstream.h @@ -0,0 +1,124 @@ +#ifndef __INKSCAPE_IO_XSLTSTREAM_H__ +#define __INKSCAPE_IO_XSLTSTREAM_H__ +/** + * Xslt-enabled input and output streams + * + * + * Authors: + * Bob Jamison <rjamison@titan.com> + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + +#include <libxslt/xslt.h> +#include <libxslt/xsltInternals.h> + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### +/** + * This is a container for reusing a loaded stylesheet + */ +class XsltStyleSheet +{ + +public: + + XsltStyleSheet(InputStream &source) throw (StreamException); + + ~XsltStyleSheet(); + + xsltStylesheetPtr stylesheet; + + +}; // class XsltStyleSheet + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream input by a given stylesheet + */ +class XsltInputStream : public BasicInputStream +{ + +public: + + XsltInputStream(InputStream &xmlSource, XsltStyleSheet &stylesheet) + throw (StreamException); + + virtual ~XsltInputStream() throw (StreamException); + + virtual int available() throw (StreamException); + + virtual void close() throw (StreamException); + + virtual int get() throw (StreamException); + + +private: + + XsltStyleSheet &stylesheet; + + xmlChar *outbuf; + int outsize; + int outpos; + +}; // class UriInputStream + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream output by a given stylesheet + */ +class XsltOutputStream : public BasicOutputStream +{ + +public: + + XsltOutputStream(OutputStream &destination, XsltStyleSheet &stylesheet) + throw (StreamException); + + virtual ~XsltOutputStream() throw (StreamException); + + virtual void close() throw (StreamException); + + virtual void flush() throw (StreamException); + + virtual void put(int ch) throw (StreamException); + +private: + + XsltStyleSheet &stylesheet; + + Glib::ustring outbuf; + + bool flushed; + +}; // class UriOutputStream + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_XSLTSTREAM_H__ */ |
