//returns a node that is nested somewhere inside this node, the path to the nested node
        //is described by a series of node names giben in 'keys'
        public TextEngineNode getNestedNodeByKey(String[] keys)
        {
            TextEngineNode tempNode = this;

            foreach (string key in keys)
            {
                if (tempNode == null)
                {
                    return(null);
                }
                else
                {
                    tempNode = tempNode.getNodeByKey(key);
                }
            }

            return(tempNode);
        }
Exemplo n.º 2
0
        private TextEngineNode parseEngineData(ByteArray bytes, uint depth)
        {
            //set up the root node that is the top of the tree
            TextEngineNode rootNode = new TextEngineNode();

            rootNode.type = TextEngineNode.TYPE_STRUCTURE;
            rootNode.key  = "root";

            long tempPos = bytes.Position;

            while (bytes.Position < bytes.Length)
            {
                //find a key
                String key = findKeyOrEnd(bytes);                 //returns null if end of structure is found
                if (key == null)
                {
                    return(rootNode);
                }

                //if we have reached this point we have found a key of the form "/keyname "
                //what follows is either a value or a structure, the following code works out which it is

                Boolean isStructure = false;

                byte b = bytes.getByte();

                //depending on the value of the next byte, we know what is going to follow
                switch (b)
                {
                case 0x20:                         //if there is a space, then a value follows
                    //little hack to get structures inside of arrays working
                    if (bytes.bytes[bytes.Position] == 0x5b && bytes.bytes[bytes.Position + 1] == 0x0a)
                    {
                        Boolean stopBracketLoop = false;
                        while (!stopBracketLoop)
                        {
                            TextEngineNode node2 = parseEngineData(bytes, depth + 1);
                            node2.key = key;
                            rootNode.structure.Add(node2);

                            if (bytes.Position == bytes.Length)
                            {
                                return(rootNode);    //massive hack just to get it working,
                                //basically it just ends if we run out of data
                            }

                            while (bytes.Position < bytes.Length)
                            {
                                b = bytes.getByte();
                                if (b != 0x09 && b != 0x3e && b != 0x0a)                                        //its a tab, so we can skip
                                {
                                    if (b == 0x5d)
                                    {
                                        stopBracketLoop = true;
                                    }
                                    else if (b == 0x3c || b == 0x2f)
                                    {
                                        //we have a new structure or property
                                    }
                                    else
                                    {
                                        if (bytes.Position == bytes.Length)
                                        {
                                            return(rootNode);    //massive hack just to get it working,
                                            //basically it just ends if we run out of data
                                        }
                                        Console.Out.WriteLine("unknown byte in middle of array at: " + bytes.Position);
                                    }

                                    break;
                                }
                            }
                        }

                        continue;
                    }
                    else
                    {
                        isStructure = false;
                    }

                    break;

                case 0x0a:                         //if its a new line, then we have found a structure
                    isStructure = true;
                    break;

                default:
                    Console.Out.WriteLine("unknown value after key: 0x" + b + ", at: " + bytes.Position);
                    break;
                }

                //now we can build the node
                TextEngineNode node;
                if (isStructure)
                {
                    //if its a structure, we use recursion to build the node
                    node     = parseEngineData(bytes, depth + 1);
                    node.key = key;
                }
                else
                {
                    //if its a value, we create a new node and fill in the value manually
                    node       = new TextEngineNode();
                    node.key   = key;
                    node.value = findValue(bytes);
                    node.type  = TextEngineNode.TYPE_VALUE;
                }

                rootNode.structure.Add(node);
            }

            return(rootNode);
        }
Exemplo n.º 3
0
        //the text engine data format is complicated, although godden told me its the
        //same as how pdf's store it
        private void parseEngineDataStructure(ByteArray bytes, long endOfTag)
        {
            byte b;

            //find the start of the data by looking for the first <
            while ((b = bytes.getByte()) != 0x3c && bytes.Position < endOfTag)
            {
            }

            //make sure we actually found one
            if (bytes.Position == endOfTag)
            {
                throw new Exception("could not find start of text engine data");
            }

            long startPos = bytes.Position;

            //we are at the start now, the end of the data will be 0x3e 0x3e 0x00
            byte firstByte  = bytes.getByte();
            byte secondByte = bytes.getByte();
            byte thirdByte  = bytes.getByte();

            //move to the start of the structure
            while (bytes.Position < endOfTag)
            {
                // 0x3e is a >
                if (firstByte == 0x3e && secondByte == 0x3e && thirdByte == 0x00)
                {
                    break;
                }

                firstByte  = secondByte;
                secondByte = thirdByte;
                thirdByte  = bytes.getByte();
            }

            if (bytes.Position == endOfTag)
            {
                throw new Exception("could not find end of text engine data");
            }

            long endPos = bytes.Position;

            //we can use the startPos and endPos to get the data in the middle
            bytes.Position = startPos;
            ByteArray engineData = bytes.getBytes((uint)(endPos - startPos));

            //engineData now contains the engineData, this code works

            TextEngineNode dataObject = parseEngineData(engineData, 0);

            //now that we have parsed all of the engineData and stored it in 'dataObject', we retreive the
            //nodes that we need

            TextEngineNode tempNode;

            tempNode = dataObject.getNestedNodeByKey(new string[] { "ResourceDict", "FontSet", "Name" });
            if (tempNode != null)
            {
                fontName = tempNode.value;
            }

            tempNode = dataObject.getNestedNodeByKey(new string[] { "EngineDict", "StyleRun", "RunArray",
                                                                    "StyleSheet", "StyleSheetData", "FontSize" });
            if (tempNode != null)
            {
                fontSize = tempNode.value;
            }

            tempNode = dataObject.getNestedNodeByKey(new string[] { "EngineDict", "Editor", "Text" });
            if (tempNode != null)
            {
                text = tempNode.value;
            }
        }