📄 compressedgeometryfile.java
字号:
* @return number of compressed objects */ public int getObjectCount() { return objectCount ; } /** * Return the current object index associated with this instance. This is * the index of the object that would be returned by an immediately * following call to the readNext() method. Its initial value is 0; -1 * is returned if the last object has been read. * * @return current object index, or -1 if at end */ public int getCurrentIndex() { if (objectIndex == objectCount) return -1 ; else return objectIndex ; } /** * Read the next compressed geometry object in the instance. This is * initially the first object (index 0) in the instance; otherwise, it is * whatever object is next after the last one read. The current object * index is incremented by 1 after the read. When the last object is read * the index becomes invalid and an immediately subsequent call to * readNext() returns null. * * @return a CompressedGeometry node component, or null if the last object * has been read * @exception IOException if read fails */ public CompressedGeometry readNext() throws IOException { return readNext(cgBuffer.length) ; } /** * Read all compressed geometry objects contained in the instance. The * current object index becomes invalid; an immediately following call * to readNext() will return null. * * @return an array of CompressedGeometry node components. * @exception IOException if read fails */ public CompressedGeometry[] read() throws IOException { long startTime = 0 ; CompressedGeometry cg[] = new CompressedGeometry[objectCount] ; if (benchmark) startTime = System.currentTimeMillis() ; objectIndex = 0 ; setFilePointer(directory[0]) ; bufferNextObjectCount = 0 ; for (int i = 0 ; i < objectCount ; i++) cg[i] = readNext(cgBuffer.length) ; if (benchmark) { long t = System.currentTimeMillis() - startTime ; System.out.println("read " + objectCount + " objects " + cgFile.length() + " bytes in " + (t/1000f) + " sec.") ; System.out.println((cgFile.length()/(float)t) + " Kbytes/sec.") ; } return cg ; } /** * Read the compressed geometry object at the specified index. The * current object index is set to the subsequent object unless the last * object has been read, in which case the index becomes invalid and an * immediately following call to readNext() will return null. * * @param index compressed geometry object to read * @return a CompressedGeometry node component * @exception IndexOutOfBoundsException if object index is * out of range * @exception IOException if read fails */ public CompressedGeometry read(int index) throws IOException { objectIndex = index ; if (objectIndex < 0) { throw new IndexOutOfBoundsException ("\nobject index must be >= 0") ; } if (objectIndex >= objectCount) { throw new IndexOutOfBoundsException ("\nobject index must be < " + objectCount) ; } // Check if object is in cache. if ((objectIndex >= bufferObjectStart) && (objectIndex < bufferObjectStart + bufferObjectCount)) { if (print) System.out.println("\ngetting object from cache\n") ; bufferNextObjectOffset = (int) (directory[objectIndex] - directory[bufferObjectStart]) ; bufferNextObjectCount = bufferObjectCount - (objectIndex - bufferObjectStart) ; return readNext() ; } else { // Move file pointer to correct offset. setFilePointer(directory[objectIndex]) ; // Force a read from current offset. Disable cache read-ahead // since cache hits are unlikely with random access. bufferNextObjectCount = 0 ; return readNext(objectSizes[objectIndex]) ; } } /** * Add a compressed geometry node component to the end of the instance. * The current object index becomes invalid; an immediately following call * to readNext() will return null. The close() method must be called at * some later time in order to create a valid compressed geometry file. * * @param cg a compressed geometry node component * @exception CapabilityNotSetException if unable to get compressed * geometry data from the node component * @exception IOException if write fails */ public void write(CompressedGeometry cg) throws IOException { CompressedGeometryHeader cgh = new CompressedGeometryHeader() ; cg.getCompressedGeometryHeader(cgh) ; // Update the read/write buffer size if necessary. if (cgh.size + BLOCK_HEADER_SIZE > cgBuffer.length) { cgBuffer = new byte[cgh.size + BLOCK_HEADER_SIZE] ; if (print) System.out.println("\ncgBuffer: reallocated " + (cgh.size+BLOCK_HEADER_SIZE) + " bytes") ; } cg.getCompressedGeometry(cgBuffer) ; write(cgh, cgBuffer) ; } /** * Add a buffer of compressed geometry data to the end of the * resource. The current object index becomes invalid; an immediately * following call to readNext() will return null. The close() method must * be called at some later time in order to create a valid compressed * geometry file. * * @param cgh a CompressedGeometryHeader object describing the data. * @param geometry the compressed geometry data * @exception IOException if write fails */ public void write(CompressedGeometryHeader cgh, byte geometry[]) throws IOException { // Update the read/write buffer size if necessary. It won't be used // in this method, but should be big enough to read any object in // the file, including the one to be written. if (cgh.size + BLOCK_HEADER_SIZE > cgBuffer.length) { cgBuffer = new byte[cgh.size + BLOCK_HEADER_SIZE] ; if (print) System.out.println("\ncgBuffer: reallocated " + (cgh.size+BLOCK_HEADER_SIZE) + " bytes") ; } // Assuming backward compatibility, the version number of the file // should be the maximum of all individual compressed object versions. if ((cgh.majorVersionNumber > majorVersionNumber) || ((cgh.majorVersionNumber == majorVersionNumber) && (cgh.minorVersionNumber > minorVersionNumber)) || ((cgh.majorVersionNumber == majorVersionNumber) && (cgh.minorVersionNumber == minorVersionNumber) && (cgh.minorMinorVersionNumber > minorMinorVersionNumber))) { majorVersionNumber = cgh.majorVersionNumber ; minorVersionNumber = cgh.minorVersionNumber ; minorMinorVersionNumber = cgh.minorMinorVersionNumber ; this.cgh.majorVersionNumber = cgh.majorVersionNumber ; this.cgh.minorVersionNumber = cgh.minorVersionNumber ; this.cgh.minorMinorVersionNumber = cgh.minorMinorVersionNumber ; } // Get the buffer type and see what vertex components are present. int geomDataType = 0 ; switch (cgh.bufferType) { case CompressedGeometryHeader.POINT_BUFFER: geomDataType = TYPE_POINT ; break ; case CompressedGeometryHeader.LINE_BUFFER: geomDataType = TYPE_LINE ; break ; case CompressedGeometryHeader.TRIANGLE_BUFFER: geomDataType = TYPE_TRIANGLE ; break ; } if ((cgh.bufferDataPresent & CompressedGeometryHeader.NORMAL_IN_BUFFER) != 0) geomDataType |= NORMAL_PRESENT_MASK ; if ((cgh.bufferDataPresent & CompressedGeometryHeader.COLOR_IN_BUFFER) != 0) geomDataType |= COLOR_PRESENT_MASK ; if ((cgh.bufferDataPresent & CompressedGeometryHeader.ALPHA_IN_BUFFER) != 0) geomDataType |= ALPHA_PRESENT_MASK ; // Allocate new directory and object size arrays if necessary. if (objectCount == directory.length) { long newDirectory[] = new long[2*objectCount] ; int newObjectSizes[] = new int[2*objectCount] ; System.arraycopy(directory, 0, newDirectory, 0, objectCount) ; System.arraycopy(objectSizes, 0, newObjectSizes, 0, objectCount) ; directory = newDirectory ; objectSizes = newObjectSizes ; if (print) System.out.println("\ndirectory and size arrays: reallocated " + (2*objectCount) + " entries") ; } // Update directory and object size array. directory[objectCount] = directoryOffset ; objectSizes[objectCount] = cgh.size + BLOCK_HEADER_SIZE ; objectCount++ ; // Seek to the directory and overwrite from there. setFilePointer(directoryOffset) ; cgFile.writeInt(cgh.size) ; cgFile.writeInt(geomDataType) ; cgFile.write(geometry, 0, cgh.size) ; if (print) System.out.println("\nwrote " + cgh.size + " byte compressed object to " + fileName + "\nfile offset " + directoryOffset) ; // Update the directory offset. directoryOffset += cgh.size + BLOCK_HEADER_SIZE ; // Return end-of-file on next read. objectIndex = objectCount ; // Flag file update so close() will write out the directory. fileUpdate = true ; } /** * Release the resources associated with this instance. * Write out final header and directory if contents were updated. * This method must be called in order to create a valid compressed * geometry resource file if any updates were made. */ public void close() { if (cgFile != null) { try { if (fileUpdate) { writeFileDirectory() ; writeFileHeader() ; } cgFile.close() ; } catch (IOException e) { // Don't propagate this exception. System.out.println("\nException: " + e.getMessage()) ; System.out.println("failed to close " + fileName) ; } } cgFile = null ; cgBuffer = null ; directory = null ; objectSizes = null ; } // // Open the file. Specifying a non-existent file creates a new one if // access permissions allow. // void open(String fname, boolean rw) throws FileNotFoundException, IOException { cgFile = null ; String mode ; if (rw) mode = "rw" ; else mode = "r" ; try { cgFile = new RandomAccessFile(fname, mode) ; if (print) System.out.println("\n" + fname + ": opened mode " + mode) ; } catch (FileNotFoundException e) { // N.B. this exception is also thrown on access permission errors throw new FileNotFoundException(e.getMessage() + "\n" + fname + ": open mode " + mode + " failed") ; } } // // Seek to the specified offset in the file. // void setFilePointer(long offset) throws IOException { cgFile.seek(offset) ; // Reset number of objects that can be read sequentially from cache. bufferNextObjectCount = 0 ; } // // Initialize directory, object size array, read/write buffer, and the // shared compressed geometry header. // void initialize() throws IOException { int maxSize = 0 ; if (cgFile.length() == 0) { // New file for writing: allocate nominal initial sizes for arrays. objectCount = 0 ; cgBuffer = new byte[32768] ; directory = new long[16] ; objectSizes = new int[directory.length] ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -