Example #1
0
 private void putkerntab() throws IOException {
   if (kernpairs == 0) return;
   in.seek(kernpairs);
   int count = in.readUnsignedShortLE();
   int nzero = 0;
   int kerns[] = new int[count * 3];
   for (int k = 0; k < kerns.length; ) {
     kerns[k++] = in.read();
     kerns[k++] = in.read();
     if ((kerns[k++] = in.readShortLE()) != 0) ++nzero;
   }
   if (nzero == 0) return;
   out.print("StartKernData\nStartKernPairs");
   outval(nzero);
   out.print('\n');
   for (int k = 0; k < kerns.length; k += 3) {
     if (kerns[k + 2] != 0) {
       out.print("KPX ");
       out.print(WinChars[kerns[k]]);
       out.print(' ');
       out.print(WinChars[kerns[k + 1]]);
       outval(kerns[k + 2]);
       out.print('\n');
     }
   }
   /* Put out trailer */
   out.print("EndKernPairs\nEndKernData\n");
 }
Example #2
0
 public void checkFdfHeader() throws IOException {
   file.setStartOffset(0);
   String str = readString(1024);
   int idx = str.indexOf("%FDF-1.2");
   if (idx < 0) throw new IOException("FDF header signature not found.");
   file.setStartOffset(idx);
 }
Example #3
0
 public char checkPdfHeader() throws IOException {
   file.setStartOffset(0);
   String str = readString(1024);
   int idx = str.indexOf("%PDF-1.");
   if (idx < 0) throw new IOException("PDF header signature not found.");
   file.setStartOffset(idx);
   return str.charAt(idx + 7);
 }
Example #4
0
 public int getStartxref() throws IOException {
   int size = Math.min(1024, file.length());
   int pos = file.length() - size;
   file.seek(pos);
   String str = readString(1024);
   int idx = str.lastIndexOf("startxref");
   if (idx < 0) throw new IOException("PDF startxref not found.");
   return pos + idx;
 }
 /** Creates the new PDF by merging the fields and forms. */
 protected void closeIt() throws IOException {
   for (int k = 0; k < readers.size(); ++k) {
     readers.get(k).removeFields();
   }
   for (int r = 0; r < readers.size(); ++r) {
     PdfReader reader = readers.get(r);
     for (int page = 1; page <= reader.getNumberOfPages(); ++page) {
       pageRefs.add(getNewReference(reader.getPageOrigRef(page)));
       pageDics.add(reader.getPageN(page));
     }
   }
   mergeFields();
   createAcroForms();
   for (int r = 0; r < readers.size(); ++r) {
     PdfReader reader = readers.get(r);
     for (int page = 1; page <= reader.getNumberOfPages(); ++page) {
       PdfDictionary dic = reader.getPageN(page);
       PdfIndirectReference pageRef = getNewReference(reader.getPageOrigRef(page));
       PdfIndirectReference parent = root.addPageRef(pageRef);
       dic.put(PdfName.PARENT, parent);
       propagate(dic, pageRef, false);
     }
   }
   for (Map.Entry<PdfReader, IntHashtable> entry : readers2intrefs.entrySet()) {
     PdfReader reader = entry.getKey();
     try {
       file = reader.getSafeFile();
       file.reOpen();
       IntHashtable t = entry.getValue();
       int keys[] = t.toOrderedKeys();
       for (int k = 0; k < keys.length; ++k) {
         PRIndirectReference ref = new PRIndirectReference(reader, keys[k]);
         addToBody(PdfReader.getPdfObjectRelease(ref), t.get(keys[k]));
       }
     } finally {
       try {
         file.close();
         // TODO: Removed - the user should be responsible for closing all PdfReaders.  But, this
         // could cause a lot of memory leaks in code out there that hasn't been properly closing
         // things - maybe add a finalizer to PdfReader that calls PdfReader#close() ??
         //                    reader.close();
       } catch (Exception e) {
         // empty on purpose
       }
     }
   }
   pdf.close();
 }
Example #6
0
 public void nextValidToken() throws IOException {
   int level = 0;
   String n1 = null;
   String n2 = null;
   int ptr = 0;
   while (nextToken()) {
     if (type == TK_COMMENT) continue;
     switch (level) {
       case 0:
         {
           if (type != TK_NUMBER) return;
           ptr = file.getFilePointer();
           n1 = stringValue;
           ++level;
           break;
         }
       case 1:
         {
           if (type != TK_NUMBER) {
             file.seek(ptr);
             type = TK_NUMBER;
             stringValue = n1;
             return;
           }
           n2 = stringValue;
           ++level;
           break;
         }
       default:
         {
           if (type != TK_OTHER || !stringValue.equals("R")) {
             file.seek(ptr);
             type = TK_NUMBER;
             stringValue = n1;
             return;
           }
           type = TK_REF;
           reference = Integer.parseInt(n1);
           generation = Integer.parseInt(n2);
           return;
         }
     }
   }
   // if we hit here, the file is either corrupt (stream ended unexpectedly),
   // or the last token ended exactly at the end of a stream.  This last
   // case can occur inside an Object Stream.
 }
Example #7
0
  private void putchartab() throws IOException {
    int count = lastchar - firstchar + 1;
    int ctabs[] = new int[count];
    in.seek(chartab);
    for (int k = 0; k < count; ++k) ctabs[k] = in.readUnsignedShortLE();
    int back[] = new int[256];
    if (charset == 0) {
      for (int i = firstchar; i <= lastchar; ++i) {
        if (Win2PSStd[i] != 0) back[Win2PSStd[i]] = i;
      }
    }
    /* Put out the header */
    out.print("StartCharMetrics");
    outval(count);
    out.print('\n');

    /* Put out all encoded chars */
    if (charset != 0) {
      /*
       * If the charset is not the Windows standard, just put out
       * unnamed entries.
       */
      for (int i = firstchar; i <= lastchar; i++) {
        if (ctabs[i - firstchar] != 0) {
          outchar(i, ctabs[i - firstchar], null);
        }
      }
    } else {
      for (int i = 0; i < 256; i++) {
        int j = back[i];
        if (j != 0) {
          outchar(i, ctabs[j - firstchar], WinChars[j]);
          ctabs[j - firstchar] = 0;
        }
      }
      /* Put out all non-encoded chars */
      for (int i = firstchar; i <= lastchar; i++) {
        if (ctabs[i - firstchar] != 0) {
          outchar(-1, ctabs[i - firstchar], WinChars[i]);
        }
      }
    }
    /* Put out the trailer */
    out.print("EndCharMetrics\n");
  }
Example #8
0
 public void nextValidToken() throws IOException {
   int level = 0;
   String n1 = null;
   String n2 = null;
   int ptr = 0;
   while (nextToken()) {
     if (type == TK_COMMENT) continue;
     switch (level) {
       case 0:
         {
           if (type != TK_NUMBER) return;
           ptr = file.getFilePointer();
           n1 = stringValue;
           ++level;
           break;
         }
       case 1:
         {
           if (type != TK_NUMBER) {
             file.seek(ptr);
             type = TK_NUMBER;
             stringValue = n1;
             return;
           }
           n2 = stringValue;
           ++level;
           break;
         }
       default:
         {
           if (type != TK_OTHER || !stringValue.equals("R")) {
             file.seek(ptr);
             type = TK_NUMBER;
             stringValue = n1;
             return;
           }
           type = TK_REF;
           reference = Integer.valueOf(n1).intValue();
           generation = Integer.valueOf(n2).intValue();
           return;
         }
     }
   }
   throwError("Unexpected end of file");
 }
Example #9
0
 private String readString(int n) throws IOException {
   byte b[] = new byte[n];
   in.readFully(b);
   int k;
   for (k = 0; k < b.length; ++k) {
     if (b[k] == 0) break;
   }
   return new String(b, 0, k, "ISO-8859-1");
 }
Example #10
0
 private String readString() throws IOException {
   StringBuffer buf = new StringBuffer();
   while (true) {
     int c = in.read();
     if (c <= 0) break;
     buf.append((char) c);
   }
   return buf.toString();
 }
Example #11
0
 void writeAllPages() throws IOException {
   try {
     file.reOpen();
     for (Iterator it = importedPages.values().iterator(); it.hasNext(); ) {
       PdfImportedPage ip = (PdfImportedPage) it.next();
       writer.addToBody(
           ip.getFormXObject(writer.getCompressionLevel()), ip.getIndirectReference());
     }
     writeAllVisited();
   } finally {
     try {
       reader.close();
       file.close();
     } catch (Exception e) {
       // Empty on purpose
     }
   }
 }
Example #12
0
 public String readString(int size) throws IOException {
   StringBuffer buf = new StringBuffer();
   int ch;
   while ((size--) > 0) {
     ch = file.read();
     if (ch == -1) break;
     buf.append((char) ch);
   }
   return buf.toString();
 }
 /**
  * If the embedded flag is <CODE>false</CODE> or if the font is one of the 14 built in types, it
  * returns <CODE>null</CODE>, otherwise the font is read and output in a PdfStream object.
  *
  * @return the PdfStream containing the font or <CODE>null</CODE>
  * @throws DocumentException if there is an error reading the font
  */
 private PdfStream getFontStream() throws DocumentException {
   if (builtinFont || !embedded) return null;
   RandomAccessFileOrArray rf = null;
   try {
     String filePfb = fileName.substring(0, fileName.length() - 3) + "pfb";
     if (pfb == null) rf = new RandomAccessFileOrArray(filePfb);
     else rf = new RandomAccessFileOrArray(pfb);
     int fileLength = rf.length();
     byte st[] = new byte[fileLength - 18];
     int lengths[] = new int[3];
     int bytePtr = 0;
     for (int k = 0; k < 3; ++k) {
       if (rf.read() != 0x80) throw new DocumentException("Start marker missing in " + filePfb);
       if (rf.read() != PFB_TYPES[k])
         throw new DocumentException("Incorrect segment type in " + filePfb);
       int size = rf.read();
       size += rf.read() << 8;
       size += rf.read() << 16;
       size += rf.read() << 24;
       lengths[k] = size;
       while (size != 0) {
         int got = rf.read(st, bytePtr, size);
         if (got < 0) throw new DocumentException("Premature end in " + filePfb);
         bytePtr += got;
         size -= got;
       }
     }
     return new StreamFont(st, lengths);
   } catch (Exception e) {
     throw new DocumentException(e);
   } finally {
     if (rf != null) {
       try {
         rf.close();
       } catch (Exception e) {
         // empty on purpose
       }
     }
   }
 }
  /**
   * Reads the font metrics
   *
   * @param rf the AFM file
   * @throws DocumentException the AFM file is invalid
   * @throws IOException the AFM file could not be read
   */
  public void process(RandomAccessFileOrArray rf) throws DocumentException, IOException {
    String line;
    boolean isMetrics = false;
    while ((line = rf.readLine()) != null) {
      StringTokenizer tok = new StringTokenizer(line, " ,\n\r\t\f");
      if (!tok.hasMoreTokens()) continue;
      String ident = tok.nextToken();
      if (ident.equals("FontName")) FontName = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("FullName")) FullName = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("FamilyName")) FamilyName = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("Weight")) Weight = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("ItalicAngle")) ItalicAngle = Float.parseFloat(tok.nextToken());
      else if (ident.equals("IsFixedPitch")) IsFixedPitch = tok.nextToken().equals("true");
      else if (ident.equals("CharacterSet")) CharacterSet = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("FontBBox")) {
        llx = (int) Float.parseFloat(tok.nextToken());
        lly = (int) Float.parseFloat(tok.nextToken());
        urx = (int) Float.parseFloat(tok.nextToken());
        ury = (int) Float.parseFloat(tok.nextToken());
      } else if (ident.equals("UnderlinePosition"))
        UnderlinePosition = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("UnderlineThickness"))
        UnderlineThickness = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("EncodingScheme"))
        EncodingScheme = tok.nextToken("\u00ff").substring(1);
      else if (ident.equals("CapHeight")) CapHeight = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("XHeight")) XHeight = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("Ascender")) Ascender = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("Descender")) Descender = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("StdHW")) StdHW = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("StdVW")) StdVW = (int) Float.parseFloat(tok.nextToken());
      else if (ident.equals("StartCharMetrics")) {
        isMetrics = true;
        break;
      }
    }
    if (!isMetrics) throw new DocumentException("Missing StartCharMetrics in " + fileName);
    while ((line = rf.readLine()) != null) {
      StringTokenizer tok = new StringTokenizer(line);
      if (!tok.hasMoreTokens()) continue;
      String ident = tok.nextToken();
      if (ident.equals("EndCharMetrics")) {
        isMetrics = false;
        break;
      }
      Integer C = new Integer(-1);
      Integer WX = new Integer(250);
      String N = "";
      int B[] = null;

      tok = new StringTokenizer(line, ";");
      while (tok.hasMoreTokens()) {
        StringTokenizer tokc = new StringTokenizer(tok.nextToken());
        if (!tokc.hasMoreTokens()) continue;
        ident = tokc.nextToken();
        if (ident.equals("C")) C = Integer.valueOf(tokc.nextToken());
        else if (ident.equals("WX")) WX = new Integer((int) Float.parseFloat(tokc.nextToken()));
        else if (ident.equals("N")) N = tokc.nextToken();
        else if (ident.equals("B")) {
          B =
              new int[] {
                Integer.parseInt(tokc.nextToken()),
                Integer.parseInt(tokc.nextToken()),
                Integer.parseInt(tokc.nextToken()),
                Integer.parseInt(tokc.nextToken())
              };
        }
      }
      Object metrics[] = new Object[] {C, WX, N, B};
      if (C.intValue() >= 0) CharMetrics.put(C, metrics);
      CharMetrics.put(N, metrics);
    }
    if (isMetrics) throw new DocumentException("Missing EndCharMetrics in " + fileName);
    if (!CharMetrics.containsKey("nonbreakingspace")) {
      Object[] space = (Object[]) CharMetrics.get("space");
      if (space != null) CharMetrics.put("nonbreakingspace", space);
    }
    while ((line = rf.readLine()) != null) {
      StringTokenizer tok = new StringTokenizer(line);
      if (!tok.hasMoreTokens()) continue;
      String ident = tok.nextToken();
      if (ident.equals("EndFontMetrics")) return;
      if (ident.equals("StartKernPairs")) {
        isMetrics = true;
        break;
      }
    }
    if (!isMetrics) throw new DocumentException("Missing EndFontMetrics in " + fileName);
    while ((line = rf.readLine()) != null) {
      StringTokenizer tok = new StringTokenizer(line);
      if (!tok.hasMoreTokens()) continue;
      String ident = tok.nextToken();
      if (ident.equals("KPX")) {
        String first = tok.nextToken();
        String second = tok.nextToken();
        Integer width = new Integer((int) Float.parseFloat(tok.nextToken()));
        Object relates[] = (Object[]) KernPairs.get(first);
        if (relates == null) KernPairs.put(first, new Object[] {second, width});
        else {
          int n = relates.length;
          Object relates2[] = new Object[n + 2];
          System.arraycopy(relates, 0, relates2, 0, n);
          relates2[n] = second;
          relates2[n + 1] = width;
          KernPairs.put(first, relates2);
        }
      } else if (ident.equals("EndKernPairs")) {
        isMetrics = false;
        break;
      }
    }
    if (isMetrics) throw new DocumentException("Missing EndKernPairs in " + fileName);
    rf.close();
  }
Example #15
0
 public int getFilePointer() throws IOException {
   return file.getFilePointer();
 }
Example #16
0
 public void backOnePosition(int ch) {
   if (ch != -1) file.pushBack((byte) ch);
 }
  /**
   * Creates a new Type1 font.
   *
   * @param ttfAfm the AFM file if the input is made with a <CODE>byte</CODE> array
   * @param pfb the PFB file if the input is made with a <CODE>byte</CODE> array
   * @param afmFile the name of one of the 14 built-in fonts or the location of an AFM file. The
   *     file must end in '.afm'
   * @param enc the encoding to be applied to this font
   * @param emb true if the font is to be embedded in the PDF
   * @throws DocumentException the AFM file is invalid
   * @throws IOException the AFM file could not be read
   */
  Type1Font(String afmFile, String enc, boolean emb, byte ttfAfm[], byte pfb[])
      throws DocumentException, IOException {
    if (emb && ttfAfm != null && pfb == null)
      throw new DocumentException("Two byte arrays are needed if the Type1 font is embedded.");
    if (emb && ttfAfm != null) this.pfb = pfb;
    encoding = enc;
    embedded = emb;
    fileName = afmFile;
    fontType = FONT_TYPE_T1;
    RandomAccessFileOrArray rf = null;
    InputStream is = null;
    if (BuiltinFonts14.containsKey(afmFile)) {
      embedded = false;
      builtinFont = true;
      byte buf[] = new byte[1024];
      try {
        if (resourceAnchor == null) resourceAnchor = new FontsResourceAnchor();
        is =
            getResourceStream(
                RESOURCE_PATH + afmFile + ".afm", resourceAnchor.getClass().getClassLoader());
        if (is == null) {
          String msg =
              afmFile
                  + " not found as resource. (The *.afm files must exist as resources in the package com.lowagie.text.pdf.fonts)";
          System.err.println(msg);
          throw new DocumentException(msg);
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        while (true) {
          int size = is.read(buf);
          if (size < 0) break;
          out.write(buf, 0, size);
        }
        buf = out.toByteArray();
      } finally {
        if (is != null) {
          try {
            is.close();
          } catch (Exception e) {
            // empty on purpose
          }
        }
      }
      try {
        rf = new RandomAccessFileOrArray(buf);
        process(rf);
      } finally {
        if (rf != null) {
          try {
            rf.close();
          } catch (Exception e) {
            // empty on purpose
          }
        }
      }
    } else if (afmFile.toLowerCase().endsWith(".afm")) {
      try {
        if (ttfAfm == null) rf = new RandomAccessFileOrArray(afmFile);
        else rf = new RandomAccessFileOrArray(ttfAfm);
        process(rf);
      } finally {
        if (rf != null) {
          try {
            rf.close();
          } catch (Exception e) {
            // empty on purpose
          }
        }
      }
    } else if (afmFile.toLowerCase().endsWith(".pfm")) {
      try {
        ByteArrayOutputStream ba = new ByteArrayOutputStream();
        if (ttfAfm == null) rf = new RandomAccessFileOrArray(afmFile);
        else rf = new RandomAccessFileOrArray(ttfAfm);
        Pfm2afm.convert(rf, ba);
        rf.close();
        rf = new RandomAccessFileOrArray(ba.toByteArray());
        process(rf);
      } finally {
        if (rf != null) {
          try {
            rf.close();
          } catch (Exception e) {
            // empty on purpose
          }
        }
      }
    } else throw new DocumentException(afmFile + " is not an AFM or PFM font file.");

    EncodingScheme = EncodingScheme.trim();
    if (EncodingScheme.equals("AdobeStandardEncoding")
        || EncodingScheme.equals("StandardEncoding")) {
      fontSpecific = false;
    }
    if (!encoding.startsWith("#"))
      PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists
    createEncoding();
  }
Example #18
0
  private void putheader() throws IOException {
    out.print("StartFontMetrics 2.0\n");
    if (copyright.length() > 0) out.print("Comment " + copyright + '\n');
    out.print("FontName ");
    in.seek(fontname);
    String fname = readString();
    out.print(fname);
    out.print("\nEncodingScheme ");
    if (charset != 0) out.print("FontSpecific\n");
    else out.print("AdobeStandardEncoding\n");
    /*
     * The .pfm is missing full name, so construct from font name by
     * changing the hyphen to a space.  This actually works in a lot
     * of cases.
     */
    out.print("FullName " + fname.replace('-', ' '));
    if (face != 0) {
      in.seek(face);
      out.print("\nFamilyName " + readString());
    }

    out.print("\nWeight ");
    if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0) out.print("Bold");
    else if ((weight < 325 && weight != 0) || fname.toLowerCase().indexOf("light") >= 0)
      out.print("Light");
    else if (fname.toLowerCase().indexOf("black") >= 0) out.print("Black");
    else out.print("Medium");

    out.print("\nItalicAngle ");
    if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0) out.print("-12.00");
    /* this is a typical value; something else may work better for a
    specific font */
    else out.print("0");

    /*
     *  The mono flag in the pfm actually indicates whether there is a
     *  table of font widths, not if they are all the same.
     */
    out.print("\nIsFixedPitch ");
    if ((kind & 1) == 0 || /* Flag for mono */ avgwidth == maxwidth) {
        /* Avg width = max width */
      out.print("true");
      isMono = true;
    } else {
      out.print("false");
      isMono = false;
    }

    /*
     * The font bounding box is lost, but try to reconstruct it.
     * Much of this is just guess work.  The bounding box is required in
     * the .afm, but is not used by the PM font installer.
     */
    out.print("\nFontBBox");
    if (isMono) outval(-20); /* Just guess at left bounds */
    else outval(-100);
    outval(-(descender + 5)); /* Descender is given as positive value */
    outval(maxwidth + 10);
    outval(ascent + 5);

    /*
     * Give other metrics that were kept
     */
    out.print("\nCapHeight");
    outval(capheight);
    out.print("\nXHeight");
    outval(xheight);
    out.print("\nDescender");
    outval(-descender);
    out.print("\nAscender");
    outval(ascender);
    out.print('\n');
  }
Example #19
0
 public int length() throws IOException {
   return file.length();
 }
Example #20
0
 public int read() throws IOException {
   return file.read();
 }
Example #21
0
 private void openpfm() throws IOException {
   in.seek(0);
   vers = in.readShortLE();
   h_len = in.readIntLE();
   copyright = readString(60);
   type = in.readShortLE();
   points = in.readShortLE();
   verres = in.readShortLE();
   horres = in.readShortLE();
   ascent = in.readShortLE();
   intleading = in.readShortLE();
   extleading = in.readShortLE();
   italic = (byte) in.read();
   uline = (byte) in.read();
   overs = (byte) in.read();
   weight = in.readShortLE();
   charset = (byte) in.read();
   pixwidth = in.readShortLE();
   pixheight = in.readShortLE();
   kind = (byte) in.read();
   avgwidth = in.readShortLE();
   maxwidth = in.readShortLE();
   firstchar = in.read();
   lastchar = in.read();
   defchar = (byte) in.read();
   brkchar = (byte) in.read();
   widthby = in.readShortLE();
   device = in.readIntLE();
   face = in.readIntLE();
   bits = in.readIntLE();
   bitoff = in.readIntLE();
   extlen = in.readShortLE();
   psext = in.readIntLE();
   chartab = in.readIntLE();
   res1 = in.readIntLE();
   kernpairs = in.readIntLE();
   res2 = in.readIntLE();
   fontname = in.readIntLE();
   if (h_len != in.length() || extlen != 30 || fontname < 75 || fontname > 512)
     throw new IOException(MessageLocalization.getComposedMessage("not.a.valid.pfm.file"));
   in.seek(psext + 14);
   capheight = in.readShortLE();
   xheight = in.readShortLE();
   ascender = in.readShortLE();
   descender = in.readShortLE();
 }
Example #22
0
 public void backOnePosition(int ch) throws IOException {
   if (ch != -1) file.pushBack((byte) ch);
 }
Example #23
0
 public boolean nextToken() throws IOException {
   StringBuffer outBuf = null;
   stringValue = EMPTY;
   int ch = 0;
   do {
     ch = file.read();
   } while (ch != -1 && isWhitespace(ch));
   if (ch == -1) return false;
   switch (ch) {
     case '[':
       type = TK_START_ARRAY;
       break;
     case ']':
       type = TK_END_ARRAY;
       break;
     case '/':
       {
         outBuf = new StringBuffer();
         type = TK_NAME;
         while (true) {
           ch = file.read();
           if (delims[ch + 1]) break;
           if (ch == '#') {
             ch = (getHex(file.read()) << 4) + getHex(file.read());
           }
           outBuf.append((char) ch);
         }
         backOnePosition(ch);
         break;
       }
     case '>':
       ch = file.read();
       if (ch != '>') throwError("'>' not expected");
       type = TK_END_DIC;
       break;
     case '<':
       {
         int v1 = file.read();
         if (v1 == '<') {
           type = TK_START_DIC;
           break;
         }
         outBuf = new StringBuffer();
         type = TK_STRING;
         hexString = true;
         int v2 = 0;
         while (true) {
           while (isWhitespace(v1)) v1 = file.read();
           if (v1 == '>') break;
           v1 = getHex(v1);
           if (v1 < 0) break;
           v2 = file.read();
           while (isWhitespace(v2)) v2 = file.read();
           if (v2 == '>') {
             ch = v1 << 4;
             outBuf.append((char) ch);
             break;
           }
           v2 = getHex(v2);
           if (v2 < 0) break;
           ch = (v1 << 4) + v2;
           outBuf.append((char) ch);
           v1 = file.read();
         }
         if (v1 < 0 || v2 < 0) throwError("Error reading string");
         break;
       }
     case '%':
       type = TK_COMMENT;
       do {
         ch = file.read();
       } while (ch != -1 && ch != '\r' && ch != '\n');
       break;
     case '(':
       {
         outBuf = new StringBuffer();
         type = TK_STRING;
         hexString = false;
         int nesting = 0;
         while (true) {
           ch = file.read();
           if (ch == -1) break;
           if (ch == '(') {
             ++nesting;
           } else if (ch == ')') {
             --nesting;
           } else if (ch == '\\') {
             boolean lineBreak = false;
             ch = file.read();
             switch (ch) {
               case 'n':
                 ch = '\n';
                 break;
               case 'r':
                 ch = '\r';
                 break;
               case 't':
                 ch = '\t';
                 break;
               case 'b':
                 ch = '\b';
                 break;
               case 'f':
                 ch = '\f';
                 break;
               case '(':
               case ')':
               case '\\':
                 break;
               case '\r':
                 lineBreak = true;
                 ch = file.read();
                 if (ch != '\n') backOnePosition(ch);
                 break;
               case '\n':
                 lineBreak = true;
                 break;
               default:
                 {
                   if (ch < '0' || ch > '7') {
                     break;
                   }
                   int octal = ch - '0';
                   ch = file.read();
                   if (ch < '0' || ch > '7') {
                     backOnePosition(ch);
                     ch = octal;
                     break;
                   }
                   octal = (octal << 3) + ch - '0';
                   ch = file.read();
                   if (ch < '0' || ch > '7') {
                     backOnePosition(ch);
                     ch = octal;
                     break;
                   }
                   octal = (octal << 3) + ch - '0';
                   ch = octal & 0xff;
                   break;
                 }
             }
             if (lineBreak) continue;
             if (ch < 0) break;
           } else if (ch == '\r') {
             ch = file.read();
             if (ch < 0) break;
             if (ch != '\n') {
               backOnePosition(ch);
               ch = '\n';
             }
           }
           if (nesting == -1) break;
           outBuf.append((char) ch);
         }
         if (ch == -1) throwError("Error reading string");
         break;
       }
     default:
       {
         outBuf = new StringBuffer();
         if (ch == '-' || ch == '+' || ch == '.' || (ch >= '0' && ch <= '9')) {
           type = TK_NUMBER;
           do {
             outBuf.append((char) ch);
             ch = file.read();
           } while (ch != -1 && ((ch >= '0' && ch <= '9') || ch == '.'));
         } else {
           type = TK_OTHER;
           do {
             outBuf.append((char) ch);
             ch = file.read();
           } while (!delims[ch + 1]);
         }
         backOnePosition(ch);
         break;
       }
   }
   if (outBuf != null) stringValue = outBuf.toString();
   return true;
 }
Example #24
0
 public void close() throws IOException {
   file.close();
 }
Example #25
0
 public void throwError(String error) throws IOException {
   throw new IOException(error + " at file pointer " + file.getFilePointer());
 }
Example #26
0
 public void seek(int pos) throws IOException {
   file.seek(pos);
 }