Click here to Skip to main content
15,894,176 members
Articles / Programming Languages / Visual Basic

Open Door - Reporting, Charts, Enquiry Drill-Downs

Rate me:
Please Sign up or sign in to vote.
4.37/5 (11 votes)
2 Feb 2009CPOL6 min read 39.4K   2K   59  
A utility for generating user editable reports, charts, documents, enquiries
using System;
using System.IO;
using System.Text;
using System.Net;
/*
 * $Id: RandomAccessFileOrArray.cs,v 1.8 2007/09/07 13:36:02 psoares33 Exp $
 * $Name:  $
 *
 * Copyright 2001, 2002 Paulo Soares
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the License.
 *
 * The Original Code is 'iText, a free JAVA-PDF library'.
 *
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
 * All Rights Reserved.
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
 *
 * Contributor(s): all the names of the contributors are added in the source code
 * where applicable.
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
 * provisions of LGPL are applicable instead of those above.  If you wish to
 * allow use of your version of this file only under the terms of the LGPL
 * License and not to allow others to use your version of this file under
 * the MPL, indicate your decision by deleting the provisions above and
 * replace them with the notice and other provisions required by the LGPL.
 * If you do not delete the provisions above, a recipient may use your version
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the MPL as stated above or under the terms of the GNU
 * Library General Public License as published by the Free Software Foundation;
 * either version 2 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
 * details.
 *
 * If you didn't download this code from the following link, you should check if
 * you aren't using an obsolete version:
 * http://www.lowagie.com/iText/
 */

namespace iTextSharp.text.pdf {
    /** An implementation of a RandomAccessFile for input only
    * that accepts a file or a byte array as data source.
    *
    * @author Paulo Soares (psoares@consiste.pt)
    */
    public class RandomAccessFileOrArray {
        
        internal FileStream rf;
        internal String filename;
        internal byte[] arrayIn;
        internal int arrayInPtr;
        internal byte back;
        internal bool isBack = false;
        
        /** Holds value of property startOffset. */
        private int startOffset = 0;
        
        public RandomAccessFileOrArray(String filename) : this(filename, false) {
        }
        
        public RandomAccessFileOrArray(String filename, bool forceRead) {
            if (!File.Exists(filename)) {
                if (filename.StartsWith("file:/") || filename.StartsWith("http://") || filename.StartsWith("https://")) {
                    Stream isp = WebRequest.Create(new Uri(filename)).GetResponse().GetResponseStream();
                    try {
                        this.arrayIn = InputStreamToArray(isp);
                        return;
                    }
                    finally {
                        try {isp.Close();}catch{}
                    }
                }
                else {
                    Stream isp = BaseFont.GetResourceStream(filename);
                    if (isp == null)
                        throw new IOException(filename + " not found as file or resource.");
                    try {
                        this.arrayIn = InputStreamToArray(isp);
                        return;
                    }
                    finally {
                        try {isp.Close();}catch{}
                    }
                }
            }
            else if (forceRead) {
                Stream s = null;
                try {
                    s = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                    this.arrayIn = InputStreamToArray(s);
                }
                finally {
                    try{if (s != null) s.Close();}catch{}
                }
                return;
            }
            this.filename = filename;
            rf = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
        }

        public RandomAccessFileOrArray(Uri url) {
            Stream isp = WebRequest.Create(url).GetResponse().GetResponseStream();
            try {
                this.arrayIn = InputStreamToArray(isp);
            }
            finally {
                try {isp.Close();}catch{}
            }
        }

        public RandomAccessFileOrArray(Stream isp) {
            this.arrayIn = InputStreamToArray(isp);
        }
        
        public static byte[] InputStreamToArray(Stream isp) {
            byte[] b = new byte[8192];
            MemoryStream outp = new MemoryStream();
            while (true) {
                int read = isp.Read(b, 0, b.Length);
                if (read < 1)
                    break;
                outp.Write(b, 0, read);
            }
            return outp.ToArray();
        }

        public RandomAccessFileOrArray(byte[] arrayIn) {
            this.arrayIn = arrayIn;
        }
        
        public RandomAccessFileOrArray(RandomAccessFileOrArray file) {
            filename = file.filename;
            arrayIn = file.arrayIn;
            startOffset = file.startOffset;
        }
        
        public void PushBack(byte b) {
            back = b;
            isBack = true;
        }
        
        public int Read() {
            if (isBack) {
                isBack = false;
                return back & 0xff;
            }
            if (arrayIn == null)
                return rf.ReadByte();
            else {
                if (arrayInPtr >= arrayIn.Length)
                    return -1;
                return arrayIn[arrayInPtr++] & 0xff;
            }
        }
        
        public int Read(byte[] b, int off, int len) {
            if (len == 0)
                return 0;
            int n = 0;
            if (isBack) {
                isBack = false;
                if (len == 1) {
                    b[off] = back;
                    return 1;
                }
                else {
                    n = 1;
                    b[off++] = back;
                    --len;
                }
            }
            if (arrayIn == null) {
                return rf.Read(b, off, len) + n;
            }
            else {
                if (arrayInPtr >= arrayIn.Length)
                    return -1;
                if (arrayInPtr + len > arrayIn.Length)
                    len = arrayIn.Length - arrayInPtr;
                Array.Copy(arrayIn, arrayInPtr, b, off, len);
                arrayInPtr += len;
                return len + n;
            }
        }
        
        public int Read(byte[] b) {
            return Read(b, 0, b.Length);
        }
        
        public void ReadFully(byte[] b) {
            ReadFully(b, 0, b.Length);
        }
        
        public void ReadFully(byte[] b, int off, int len) {
            if (len == 0)
                return;
            int n = 0;
            do {
                int count = Read(b, off + n, len - n);
                if (count <= 0)
                    throw new EndOfStreamException();
                n += count;
            } while (n < len);
        }
        
        public long Skip(long n) {
            return SkipBytes((int)n);
        }
        
        public int SkipBytes(int n) {
            if (n <= 0) {
                return 0;
            }
            int adj = 0;
            if (isBack) {
                isBack = false;
                if (n == 1) {
                    return 1;
                }
                else {
                    --n;
                    adj = 1;
                }
            }
            int pos;
            int len;
            int newpos;
            
            pos = FilePointer;
            len = Length;
            newpos = pos + n;
            if (newpos > len) {
                newpos = len;
            }
            Seek(newpos);
            
            /* return the actual number of bytes skipped */
            return newpos - pos + adj;
        }
        
        public void ReOpen() {
            if (filename != null && rf == null)
                rf = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            Seek(0);
        }
        
        protected void InsureOpen() {
            if (filename != null && rf == null) {
                ReOpen();
            }
        }
        
        public bool IsOpen() {
            return (filename == null || rf != null);
        }
        
        public void Close() {
            isBack = false;
            if (rf != null) {
                rf.Close();
                rf = null;
            }
        }
        
        public int Length {
            get {
                if (arrayIn == null) {
                    InsureOpen();
                    return (int)rf.Length - startOffset;
                }
                else
                    return arrayIn.Length - startOffset;
            }
        }
        
        public void Seek(int pos) {
            pos += startOffset;
            isBack = false;
            if (arrayIn == null) {
                InsureOpen();
                rf.Position = pos;
            }
            else
                arrayInPtr = pos;
        }
        
        public void Seek(long pos) {
            Seek((int)pos);
        }
        
        public int FilePointer {
            get {
                InsureOpen();
                int n = isBack ? 1 : 0;
                if (arrayIn == null) {
                    return (int)rf.Position - n - startOffset;
                }
                else
                    return arrayInPtr - n - startOffset;
            }
        }
        
        public bool ReadBoolean() {
            int ch = this.Read();
            if (ch < 0)
                throw new EndOfStreamException();
            return (ch != 0);
        }
        
        public byte ReadByte() {
            int ch = this.Read();
            if (ch < 0)
                throw new EndOfStreamException();
            return (byte)(ch);
        }
        
        public int ReadUnsignedByte() {
            int ch = this.Read();
            if (ch < 0)
                throw new EndOfStreamException();
            return ch;
        }
        
        public short ReadShort() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (short)((ch1 << 8) + ch2);
        }
        
        /**
        * Reads a signed 16-bit number from this stream in little-endian order.
        * The method reads two
        * bytes from this stream, starting at the current stream pointer.
        * If the two bytes read, in order, are
        * <code>b1</code> and <code>b2</code>, where each of the two values is
        * between <code>0</code> and <code>255</code>, inclusive, then the
        * result is equal to:
        * <blockquote><pre>
        *     (short)((b2 &lt;&lt; 8) | b1)
        * </pre></blockquote>
        * <p>
        * This method blocks until the two bytes are read, the end of the
        * stream is detected, or an exception is thrown.
        *
        * @return     the next two bytes of this stream, interpreted as a signed
        *             16-bit number.
        * @exception  EOFException  if this stream reaches the end before reading
        *               two bytes.
        * @exception  IOException   if an I/O error occurs.
        */
        public short ReadShortLE() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (short)((ch2 << 8) + (ch1 << 0));
        }
        
        public int ReadUnsignedShort() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (ch1 << 8) + ch2;
        }
        
        /**
        * Reads an unsigned 16-bit number from this stream in little-endian order.
        * This method reads
        * two bytes from the stream, starting at the current stream pointer.
        * If the bytes read, in order, are
        * <code>b1</code> and <code>b2</code>, where
        * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>,
        * then the result is equal to:
        * <blockquote><pre>
        *     (b2 &lt;&lt; 8) | b1
        * </pre></blockquote>
        * <p>
        * This method blocks until the two bytes are read, the end of the
        * stream is detected, or an exception is thrown.
        *
        * @return     the next two bytes of this stream, interpreted as an
        *             unsigned 16-bit integer.
        * @exception  EOFException  if this stream reaches the end before reading
        *               two bytes.
        * @exception  IOException   if an I/O error occurs.
        */
        public int ReadUnsignedShortLE() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (ch2 << 8) + (ch1 << 0);
        }
        
        public char ReadChar() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (char)((ch1 << 8) + ch2);
        }
        
        /**
        * Reads a Unicode character from this stream in little-endian order.
        * This method reads two
        * bytes from the stream, starting at the current stream pointer.
        * If the bytes read, in order, are
        * <code>b1</code> and <code>b2</code>, where
        * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>,
        * then the result is equal to:
        * <blockquote><pre>
        *     (char)((b2 &lt;&lt; 8) | b1)
        * </pre></blockquote>
        * <p>
        * This method blocks until the two bytes are read, the end of the
        * stream is detected, or an exception is thrown.
        *
        * @return     the next two bytes of this stream as a Unicode character.
        * @exception  EOFException  if this stream reaches the end before reading
        *               two bytes.
        * @exception  IOException   if an I/O error occurs.
        */
        public char ReadCharLE() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            if ((ch1 | ch2) < 0)
                throw new EndOfStreamException();
            return (char)((ch2 << 8) + (ch1 << 0));
        }
        
        public int ReadInt() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            int ch3 = this.Read();
            int ch4 = this.Read();
            if ((ch1 | ch2 | ch3 | ch4) < 0)
                throw new EndOfStreamException();
            return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
        }
        
        /**
        * Reads a signed 32-bit integer from this stream in little-endian order.
        * This method reads 4
        * bytes from the stream, starting at the current stream pointer.
        * If the bytes read, in order, are <code>b1</code>,
        * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
        * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
        * then the result is equal to:
        * <blockquote><pre>
        *     (b4 &lt;&lt; 24) | (b3 &lt;&lt; 16) + (b2 &lt;&lt; 8) + b1
        * </pre></blockquote>
        * <p>
        * This method blocks until the four bytes are read, the end of the
        * stream is detected, or an exception is thrown.
        *
        * @return     the next four bytes of this stream, interpreted as an
        *             <code>int</code>.
        * @exception  EOFException  if this stream reaches the end before reading
        *               four bytes.
        * @exception  IOException   if an I/O error occurs.
        */
        public int ReadIntLE() {
            int ch1 = this.Read();
            int ch2 = this.Read();
            int ch3 = this.Read();
            int ch4 = this.Read();
            if ((ch1 | ch2 | ch3 | ch4) < 0)
                throw new EndOfStreamException();
            return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
        }
        
        /**
        * Reads an unsigned 32-bit integer from this stream. This method reads 4
        * bytes from the stream, starting at the current stream pointer.
        * If the bytes read, in order, are <code>b1</code>,
        * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
        * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
        * then the result is equal to:
        * <blockquote><pre>
        *     (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
        * </pre></blockquote>
        * <p>
        * This method blocks until the four bytes are read, the end of the
        * stream is detected, or an exception is thrown.
        *
        * @return     the next four bytes of this stream, interpreted as a
        *             <code>long</code>.
        * @exception  EOFException  if this stream reaches the end before reading
        *               four bytes.
        * @exception  IOException   if an I/O error occurs.
        */
        public long ReadUnsignedInt() {
            long ch1 = this.Read();
            long ch2 = this.Read();
            long ch3 = this.Read();
            long ch4 = this.Read();
            if ((ch1 | ch2 | ch3 | ch4) < 0)
                throw new EndOfStreamException();
            return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
        }
        
        public long ReadUnsignedIntLE() {
            long ch1 = this.Read();
            long ch2 = this.Read();
            long ch3 = this.Read();
            long ch4 = this.Read();
            if ((ch1 | ch2 | ch3 | ch4) < 0)
                throw new EndOfStreamException();
            return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
        }
        
        public long ReadLong() {
            return ((long)(ReadInt()) << 32) + (ReadInt() & 0xFFFFFFFFL);
        }
        
        public long ReadLongLE() {
            int i1 = ReadIntLE();
            int i2 = ReadIntLE();
            return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL);
        }
        
        public float ReadFloat() {
            int[] a = {ReadInt()};
            float[] b = {0};
            Buffer.BlockCopy(a, 0, b, 0, 4);
            return b[0];
        }
        
        public float ReadFloatLE() {
            int[] a = {ReadIntLE()};
            float[] b = {0};
            Buffer.BlockCopy(a, 0, b, 0, 4);
            return b[0];
        }
        
        public double ReadDouble() {
            long[] a = {ReadLong()};
            double[] b = {0};
            Buffer.BlockCopy(a, 0, b, 0, 8);
            return b[0];
        }
        
        public double ReadDoubleLE() {
            long[] a = {ReadLongLE()};
            double[] b = {0};
            Buffer.BlockCopy(a, 0, b, 0, 8);
            return b[0];
        }

    public String ReadLine() {
            StringBuilder input = new StringBuilder();
            int c = -1;
            bool eol = false;
            
            while (!eol) {
                switch (c = Read()) {
                    case -1:
                    case '\n':
                        eol = true;
                        break;
                    case '\r':
                        eol = true;
                        int cur = FilePointer;
                        if ((Read()) != '\n') {
                            Seek(cur);
                        }
                        break;
                    default:
                        input.Append((char)c);
                        break;
                }
            }
            
            if ((c == -1) && (input.Length == 0)) {
                return null;
            }
            return input.ToString();
        }
        
        public int StartOffset {
            get {
                return startOffset;
            }
            set {
                startOffset = value;
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions