void processCommands()

in poi-scratchpad/src/main/java/org/apache/poi/hdgf/chunks/Chunk.java [138:261]


    void processCommands() {
        if(commandDefinitions == null) {
            throw new IllegalStateException("You must supply the command definitions before calling processCommands!");
        }

        // Loop over the definitions, building the commands
        //  and getting their values
        ArrayList<Command> commandList = new ArrayList<>();
        for(CommandDefinition cdef : commandDefinitions) {
            int type = cdef.getType();
            int offset = cdef.getOffset();

            // Handle virtual commands
            if(type == 10) {
                name = cdef.getName();
                continue;
            } else if(type == 18) {
                continue;
            }


            // Build the appropriate command for the type
            Command command;
            if(type == 11 || type == 21) {
                command = new BlockOffsetCommand(cdef);
            } else {
                command = new Command(cdef);
            }

            // Bizarrely, many of the offsets are from the start of the
            //  header, not from the start of the chunk body
            switch(type) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
            case 11: case 21:
            case 12: case 16: case 17: case 28: case 29:
                // Offset is from start of chunk (case 18 has been taken care of above)
                break;
            default:
                // Offset is from start of header!
                if(offset >= 19) {
                    offset -= 19;
                }
            }

            // Check we seem to have enough data
            if(offset >= contents.length) {
                LOG.atWarn().log("Command offset {} past end of data at {}", box(offset),box(contents.length));
                continue;
            }

            try {
                // Process
                switch(type) {
                // Types 0->7 = a flag at bit 0->7
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                    command.value = ((contents[offset] >>> type) & 1) == 1;
                    break;
                case 8:
                    command.value = contents[offset];
                    break;
                case 9:
                    command.value = LittleEndian.getDouble(contents, offset);
                    break;
                case 12:
                    // A Little Endian String
                    // Starts 8 bytes into the data segment
                    // Ends at end of data, or 00 00

                    // Ensure we have enough data
                    if(contents.length < 8) {
                        command.value = "";
                        break;
                    }

                    // Find the end point
                    int startsAt = 8;
                    int endsAt = startsAt;
                    for(int j=startsAt; j<contents.length-1 && endsAt == startsAt; j++) {
                        if(contents[j] == 0 && contents[j+1] == 0) {
                            endsAt = j;
                        }
                    }
                    if(endsAt == startsAt) {
                        endsAt = contents.length;
                    }

                    int strLen = endsAt - startsAt;
                    command.value = new String(contents, startsAt, strLen, header.getChunkCharset());
                    break;
                case 25:
                    command.value = LittleEndian.getShort(contents, offset);
                    break;
                case 26:
                    command.value = LittleEndian.getInt(contents, offset);
                    break;

                // Types 11 and 21 hold the offset to the blocks
                case 11: case 21:
                    if(offset < contents.length - 3) {
                        int bOffset = (int)LittleEndian.getUInt(contents, offset);
                        BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
                        bcmd.setOffset(bOffset);
                    }
                    break;

                default:
                    LOG.atInfo().log("Command of type {} not processed!", box(type));
                }
            }
            catch (Exception e) {
                LOG.atError().withThrowable(e).log("Unexpected error processing command, ignoring and continuing. Command: {}", command);
            }

            // Add to the array
            commandList.add(command);
        }

        // Save the commands we liked the look of
        this.commands = commandList.toArray(
                new Command[0]);

        // Now build up the blocks, if we had a command that tells
        //  us where a block is
    }