private void StoreInA() { IIByteArrayHolder byteArrayHolder = new ByteArrayHolder(CreateByteArray()); A().Provider().StoreNew(byteArrayHolder); A().Provider().Commit(); EnsureNames(A(), initial); }
/// <summary> Gets the chars in the ascii array, taking into account continuation /// breaks /// /// </summary> /// <param name="source">the original source /// </param> /// <param name="bah">holder for the new byte array /// </param> /// <param name="pos">the current position in the source /// </param> /// <param name="ascii">holder for a return ascii flag /// </param> /// <param name="numChars">the number of chars in the string /// </param> /// <returns> the number of bytes read from the source /// </returns> private int getChars(sbyte[] source, ByteArrayHolder bah, int pos, BooleanHolder ascii, int numChars) { int i = 0; bool spansBreak = false; // byte[] bytes = null; if (ascii.Value) { bah.bytes = new sbyte[numChars]; } else { bah.bytes = new sbyte[numChars * 2]; } while (i < continuationBreaks.Length && !spansBreak) { spansBreak = pos <= continuationBreaks[i] && (pos + bah.bytes.Length > continuationBreaks[i]); if (!spansBreak) { i++; } } // If it doesn't span a break simply do an array copy into the // destination array and finish if (!spansBreak) { Array.Copy(source, pos, bah.bytes, 0, bah.bytes.Length); return(bah.bytes.Length); } // Copy the portion before the break pos into the array int breakpos = continuationBreaks[i]; Array.Copy(source, pos, bah.bytes, 0, breakpos - pos); int bytesRead = breakpos - pos; int charsRead; if (ascii.Value) { charsRead = bytesRead; } else { charsRead = bytesRead / 2; } bytesRead += getContinuedString(source, bah, bytesRead, i, ascii, numChars - charsRead); return(bytesRead); }
/** * Reads in all the strings from the raw data * * @param data the raw data * @param offset the offset * @param ws the workbook settings */ private void readStrings(byte[] data,int offset,WorkbookSettings ws) { int pos = offset; int numChars; byte optionFlags; string s = null; bool asciiEncoding = false; bool richString = false; bool extendedString = false; int formattingRuns = 0; int extendedRunLength = 0; for (int i = 0; i < uniqueStrings; i++) { // Read in the number of characters numChars = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; optionFlags = data[pos]; pos++; // See if it is an extended string extendedString = ((optionFlags & 0x04) != 0); // See if string contains formatting information richString = ((optionFlags & 0x08) != 0); if (richString) { // Read in the crun formattingRuns = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; } if (extendedString) { // Read in cchExtRst extendedRunLength = IntegerHelper.getInt (data[pos],data[pos + 1],data[pos + 2],data[pos + 3]); pos += 4; } // See if string is ASCII (compressed) or unicode asciiEncoding = ((optionFlags & 0x01) == 0); ByteArrayHolder bah = new ByteArrayHolder(); BooleanHolder bh = new BooleanHolder(); bh.value = asciiEncoding; pos += getChars(data,bah,pos,bh,numChars); asciiEncoding = bh.value; if (asciiEncoding) { s = StringHelper.getString(bah.bytes,numChars,0,ws); } else { s = StringHelper.getUnicodeString(bah.bytes,numChars,0); } strings[i] = s; // For rich strings, skip over the formatting runs if (richString) { pos += 4 * formattingRuns; } // For extended strings, skip over the extended string data if (extendedString) { pos += extendedRunLength; } if (pos > data.Length) { Assert.verify(false,"pos exceeds record length"); } } }
/** * Gets the rest of the string after a continuation break * * @param source the original bytes * @param bah the holder for the new bytes * @param destPos the des pos * @param contBreakIndex the index of the continuation break * @param ascii the ascii flag holder * @param charsLeft the number of chars left in the array * @return the number of bytes read in the continued string */ private int getContinuedString(byte[] source, ByteArrayHolder bah, int destPos, int contBreakIndex, BooleanHolder ascii, int charsLeft) { int breakpos = continuationBreaks[contBreakIndex]; int bytesRead = 0; while (charsLeft > 0) { Assert.verify(contBreakIndex < continuationBreaks.Length, "continuation break index"); if (ascii.value && source[breakpos] == 0) { // The string is consistently ascii throughout int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft : System.Math.Min(charsLeft,continuationBreaks[contBreakIndex + 1] - breakpos - 1); System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length; ascii.value = true; } else if (!ascii.value && source[breakpos] != 0) { // The string is Unicode throughout int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft * 2 : System.Math.Min(charsLeft * 2,continuationBreaks[contBreakIndex + 1] - breakpos - 1); // It looks like the string continues as Unicode too. That's handy System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length / 2; ascii.value = false; } else if (!ascii.value && source[breakpos] == 0) { // Bummer - the string starts off as Unicode, but after the // continuation it is in straightforward ASCII encoding int chars = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft : System.Math.Min(charsLeft,continuationBreaks[contBreakIndex + 1] - breakpos - 1); for (int j = 0; j < chars; j++) { bah.bytes[destPos] = source[breakpos + j + 1]; destPos += 2; } bytesRead += chars + 1; charsLeft -= chars; ascii.value = false; } else { // Double Bummer - the string starts off as ASCII, but after the // continuation it is in Unicode. This impacts the allocated array // Reallocate what we have of the byte array so that it is all // Unicode byte[] oldBytes = bah.bytes; bah.bytes = new byte[destPos * 2 + charsLeft * 2]; for (int j = 0; j < destPos; j++) { bah.bytes[j * 2] = oldBytes[j]; } destPos = destPos * 2; int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft * 2 : System.Math.Min(charsLeft * 2,continuationBreaks[contBreakIndex + 1] - breakpos - 1); System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length / 2; ascii.value = false; } contBreakIndex++; if (contBreakIndex < continuationBreaks.Length) { breakpos = continuationBreaks[contBreakIndex]; } } return bytesRead; }
/** * Gets the chars in the ascii array, taking into account continuation * breaks * * @param source the original source * @param bah holder for the new byte array * @param pos the current position in the source * @param ascii holder for a return ascii flag * @param numChars the number of chars in the string * @return the number of bytes read from the source */ private int getChars(byte[] source, ByteArrayHolder bah, int pos, BooleanHolder ascii, int numChars) { int i = 0; bool spansBreak = false; if (ascii.value) bah.bytes = new byte[numChars]; else bah.bytes = new byte[numChars * 2]; while (i < continuationBreaks.Length && !spansBreak) { spansBreak = pos <= continuationBreaks[i] && (pos + bah.bytes.Length > continuationBreaks[i]); if (!spansBreak) { i++; } } // If it doesn't span a break simply do an array copy into the // destination array and finish if (!spansBreak) { System.Array.Copy(source,pos,bah.bytes,0,bah.bytes.Length); return bah.bytes.Length; } // Copy the portion before the break pos into the array int breakpos = continuationBreaks[i]; System.Array.Copy(source,pos,bah.bytes,0,breakpos - pos); int bytesRead = breakpos - pos; int charsRead; if (ascii.value) { charsRead = bytesRead; } else { charsRead = bytesRead / 2; } bytesRead += getContinuedString(source, bah, bytesRead, i, ascii, numChars - charsRead); return bytesRead; }
/** * Gets the rest of the string after a continuation break * * @param source the original bytes * @param bah the holder for the new bytes * @param destPos the des pos * @param contBreakIndex the index of the continuation break * @param ascii the ascii flag holder * @param charsLeft the number of chars left in the array * @return the number of bytes read in the continued string */ private int getContinuedString(byte[] source, ByteArrayHolder bah, int destPos, int contBreakIndex, BooleanHolder ascii, int charsLeft) { int breakpos = continuationBreaks[contBreakIndex]; int bytesRead = 0; while (charsLeft > 0) { Assert.verify(contBreakIndex < continuationBreaks.Length, "continuation break index"); if (ascii.value && source[breakpos] == 0) { // The string is consistently ascii throughout int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft : System.Math.Min(charsLeft, continuationBreaks[contBreakIndex + 1] - breakpos - 1); System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length; ascii.value = true; } else if (!ascii.value && source[breakpos] != 0) { // The string is Unicode throughout int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft * 2 : System.Math.Min(charsLeft * 2, continuationBreaks[contBreakIndex + 1] - breakpos - 1); // It looks like the string continues as Unicode too. That's handy System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length / 2; ascii.value = false; } else if (!ascii.value && source[breakpos] == 0) { // Bummer - the string starts off as Unicode, but after the // continuation it is in straightforward ASCII encoding int chars = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft : System.Math.Min(charsLeft, continuationBreaks[contBreakIndex + 1] - breakpos - 1); for (int j = 0; j < chars; j++) { bah.bytes[destPos] = source[breakpos + j + 1]; destPos += 2; } bytesRead += chars + 1; charsLeft -= chars; ascii.value = false; } else { // Double Bummer - the string starts off as ASCII, but after the // continuation it is in Unicode. This impacts the allocated array // Reallocate what we have of the byte array so that it is all // Unicode byte[] oldBytes = bah.bytes; bah.bytes = new byte[destPos * 2 + charsLeft * 2]; for (int j = 0; j < destPos; j++) { bah.bytes[j * 2] = oldBytes[j]; } destPos = destPos * 2; int length = contBreakIndex == continuationBreaks.Length - 1 ? charsLeft * 2 : System.Math.Min(charsLeft * 2, continuationBreaks[contBreakIndex + 1] - breakpos - 1); System.Array.Copy(source, breakpos + 1, bah.bytes, destPos, length); destPos += length; bytesRead += length + 1; charsLeft -= length / 2; ascii.value = false; } contBreakIndex++; if (contBreakIndex < continuationBreaks.Length) { breakpos = continuationBreaks[contBreakIndex]; } } return(bytesRead); }
/** * Reads in all the strings from the raw data * * @param data the raw data * @param offset the offset * @param ws the workbook settings */ private void readStrings(byte[] data, int offset, WorkbookSettings ws) { int pos = offset; int numChars; byte optionFlags; string s = null; bool asciiEncoding = false; bool richString = false; bool extendedString = false; int formattingRuns = 0; int extendedRunLength = 0; for (int i = 0; i < uniqueStrings; i++) { // Read in the number of characters numChars = IntegerHelper.getInt(data[pos], data[pos + 1]); pos += 2; optionFlags = data[pos]; pos++; // See if it is an extended string extendedString = ((optionFlags & 0x04) != 0); // See if string contains formatting information richString = ((optionFlags & 0x08) != 0); if (richString) { // Read in the crun formattingRuns = IntegerHelper.getInt(data[pos], data[pos + 1]); pos += 2; } if (extendedString) { // Read in cchExtRst extendedRunLength = IntegerHelper.getInt (data[pos], data[pos + 1], data[pos + 2], data[pos + 3]); pos += 4; } // See if string is ASCII (compressed) or unicode asciiEncoding = ((optionFlags & 0x01) == 0); ByteArrayHolder bah = new ByteArrayHolder(); BooleanHolder bh = new BooleanHolder(); bh.value = asciiEncoding; pos += getChars(data, bah, pos, bh, numChars); asciiEncoding = bh.value; if (asciiEncoding) { s = StringHelper.getString(bah.bytes, numChars, 0, ws); } else { s = StringHelper.getUnicodeString(bah.bytes, numChars, 0); } strings[i] = s; // For rich strings, skip over the formatting runs if (richString) { pos += 4 * formattingRuns; } // For extended strings, skip over the extended string data if (extendedString) { pos += extendedRunLength; } if (pos > data.Length) { Assert.verify(false, "pos exceeds record length"); } } }