internal override bool Transform(string propName, string propData, ResolutionContext ctx, ConvertionManager cm, ExtensionResolution ex) { // convert to custom type (with an ObjectConverter registered in ConvertionManager). var objectConverter = cm.TryGet(typeof(string), ExtensionDataType); if (objectConverter == null) { return(false); } // if an property value is provided for the property name, try to convert it. object propValue; if (!objectConverter.TryConvert(propData, out propValue)) { return(false); } var holder = new BooleanHolder(propValue); ex.Data.AddDataHolder(propName, holder); return(true); }
/** * 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; }
public DatabaseInserter(BooleanHolder holder) { this.holder = holder; }
/** * 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); }
/** * 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"); } } }
// Notes that this method will load the related assembly which defined the IExtensionBuilder implementation into memory. /// <summary> /// The required properties of extension builder (marked by ExtensionDataAttribute) must be provided by the extension data. /// </summary> /// <returns></returns> internal static bool ExtensionDataMatchesExtensionBuilder(this ExtensionResolution ex, IMessageDialog dialog, ResolutionContext ctx, ConvertionManager convertionManager) { var ebProperties = ex.ExtensionBuilder.Type.GetSettableRuntimeProperties(); if (ebProperties == null) { return(true); } var data = ex.Data; foreach (var ebProp in ebProperties) { var propName = ebProp.Name; string propInput; if (!data.TryGetString(propName, out propInput)) { var exPropAttrib = ebProp.GetCustomAttribute <ExtensionPropertyAttribute>(false, false); if (exPropAttrib != null && exPropAttrib.Required) { dialog.AddError("a required property is missing!"); return(false); } continue; } #region specific types if (ebProp.PropertyType == typeof(string)) { var holder = new StringHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } // convert to TypeId if (ebProp.PropertyType == typeof(TypeId)) { TypeResolution type; // a type dependency is introduced here. // should it be added to the current addin's reference set? if (!ctx.TryGetAddinType(ex.DeclaringAddin, propInput, out type)) { dialog.AddError(""); return(false); } var holder = new LazyTypeIdHolder(type); data.AddSerializableHolder(propName, holder); continue; } #endregion // convert to custom type (with an ObjectConverter registered in ConvertionManager). var objectConverter = convertionManager.TryGet(typeof(string), ebProp.PropertyType); if (objectConverter == null) { dialog.AddError("No converter is registered for !"); return(false); } // if an property value is provided for the property name, try to convert it. object propValue; if (!objectConverter.TryConvert(propInput, out propValue)) { dialog.AddError("The string [] can not be converted to !"); return(false); } #region common types if (ebProp.PropertyType == typeof(Int32)) { var holder = new Int32Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Boolean)) { var holder = new BooleanHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Version)) { var holder = new VersionHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(DateTime)) { var holder = new DateTimeHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Guid)) { var holder = new GuidHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(TimeSpan)) { var holder = new TimeSpanHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Int64)) { var holder = new Int64Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt64)) { var holder = new UInt64Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt32)) { var holder = new UInt32Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Int16)) { var holder = new Int16Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(UInt16)) { var holder = new UInt16Holder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Byte)) { var holder = new ByteHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(SByte)) { var holder = new SByteHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Char)) { var holder = new CharHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Decimal)) { var holder = new DecimalHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Double)) { var holder = new DoubleHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } if (ebProp.PropertyType == typeof(Single)) { var holder = new SingleHolder(propInput); data.AddSerializableHolder(propName, holder); continue; } #endregion } return(true); }