using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;
namespace Parse720
{
[AttributeUsage(System.AttributeTargets.Field)]
class FP : Attribute
{
public int startOffset;
public int endOffset;
public bool hasDecimal;
public bool hasSign;
public FP(int startOffset)
{
this.startOffset = startOffset;
this.endOffset = startOffset;
}
public FP(int startOffset, int endOffset)
{
this.startOffset = startOffset;
this.endOffset = endOffset;
}
}
public class RegistroDeclarante
{
[FP(1)]
public string TipoDeRegistro;
[FP(2,4)]
public string ModeloDeclaracion;
[FP(5, 8)]
public string Ejercicio;
[FP(9, 17)]
public string NifDeclarante;
[FP(18,57)]
public string ApellidosYNombre;
[FP(58)]
public string TipoDeSoporte;
[FP(59,67)]
public string Rel_Telefono;
[FP(68,107)]
public string Rel_ApellidosYNombre;
[FP(108,120)]
public string NiDeclaracion;
[FP(121)]
public string DecComplementaria;
[FP(122)]
public string DecSustitutiva;
[FP(123,135)]
public string NiDeclaracionAnterior;
[FP(136,144)]
public decimal NumeroTotalDeRegistrosDecl;
[FP(145,162, hasSign=true, hasDecimal=true)]
public decimal SumaTotalValoracion1;
[FP(163,180, hasSign=true, hasDecimal=true)]
public decimal SumaTotalValoracion2;
[FP(181,500)]
public string blanco;
}
public class RegistroDetalle
{
[FP(1)]
public string Tipo;
[FP(2,4)]
public string Modelo;
[FP(5,8)]
public string Ejercicio;
[FP(9, 17)]
public string NIF_Declarante;
[FP(18, 26)]
public string NIF_Declarado;
[FP(27, 35)]
public string NIF_RepresentanteLegal;
[FP(36, 75)]
public string ApellidosYNombreDeclarado;
[FP(76)]
public string ClaveDeclarante;
[FP(77, 101)]
public string TipoDeTitualidad;
[FP(102)]
public string ClaveDeBien;
[FP(103)]
public string SubclaveDeBien;
[FP(104, 128)]
public string TipoDeDerechoInmueble;
[FP(129, 130)]
public string CodigoDePais;
[FP(131)]
public string ClaveId;
[FP(132, 143)]
public string IdValores;
[FP(144)]
public string ClaveDeIdentifacation;
[FP(144, 155)]
public string CodigoBIC;
[FP(156, 189)]
public string CodigoCuenta;
[FP(190, 230)]
public string IdentificationEntidad;
[FP(231, 250)]
public string NIFEnPaisResidencial;
[FP(251, 302)]
public string DomicilioEntidad_Via;
[FP(303, 342)]
public string DomicilioEntidad_Comp;
[FP(343, 372)]
public string DomicilioEntidad_Ciudad;
[FP(373, 402)]
public string DomicilioEntidad_Provincia;
[FP(403, 412)]
public string DomicilioEntidad_CodigoPostal;
[FP(413, 414)]
public string DomicilioEntidad_CodigoPais;
[FP(415, 422)]
public DateTime FechaIncorporacion;
[FP(423)]
public string OrigenDelBien;
[FP(424, 431)]
public DateTime FechaExtincion;
[FP(432,446, hasSign=true, hasDecimal=true)]
public decimal Valoracion1;
[FP(447,461, hasSign=true, hasDecimal=true)]
public decimal Valoracion2;
[FP(462)]
public string RepresentacionDeValores;
[FP(463,474, hasDecimal=true)]
public decimal NumeroDeValores;
[FP(475)]
public string TipoInmueble;
[FP(476,480, hasDecimal=true)]
public decimal PorcentageParticipacion;
[FP(481,500)]
public string Blancos;
}
class Process720
{
static void WriteBuffer<T>(T item, char[] buffer)
{
for(int i=0;i<500;i++)
{
buffer[i] = \' \';
}
foreach (var field in typeof(T).GetFields())
{
object[] attr = field.GetCustomAttributes(typeof(FP), false);
if (attr == null || attr.Length == 0)
continue;
string v = "";
FP fp = (FP)attr[0];
if (field.FieldType == typeof(string))
{
v = (string)field.GetValue(item);
if (v == null)
v = "";
}
else if (field.FieldType == typeof(decimal))
{
decimal dv = (decimal)field.GetValue(item);
v = "";
int lengthLeft = fp.endOffset - fp.startOffset + 1;
if (fp.hasSign)
{
if (dv < 0)
{
v = "N";
}
else
{
v = " ";
}
lengthLeft--;
}
if (fp.hasDecimal)
{
v += dv.ToString(new string(\'0\', lengthLeft - 2) + ".00", CultureInfo.InvariantCulture).Replace(".", "");
}
else
{
v += dv.ToString(new string(\'0\', lengthLeft), CultureInfo.InvariantCulture);
}
}
else if (field.FieldType == typeof(DateTime))
{
DateTime dv = (DateTime)field.GetValue(item);
if (dv == default(DateTime))
{
v = "00000000";
}
else
{
v = dv.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
}
}
else
{
throw new ApplicationException("unknown field type");
}
if (v.Length > fp.endOffset - fp.startOffset + 1)
{
throw new ApplicationException("too big");
}
for (int i = 0; i < v.Length; i++ )
{
buffer[i + fp.startOffset - 1] = v[i];
}
}
}
static T ParseBuffer<T>(char[] buffer) where T : new()
{
T t = new T();
foreach( var field in typeof(T).GetFields())
{
object[] attr = field.GetCustomAttributes(typeof(FP), false);
if (attr == null || attr.Length == 0)
continue;
FP fp = (FP)attr[0];
string v = new string(buffer, fp.startOffset - 1, fp.endOffset - fp.startOffset + 1);
if (field.FieldType == typeof(string))
{
field.SetValue(t, v);
}
else if (field.FieldType == typeof(decimal))
{
if (fp.hasSign)
{
if (v[0] == \'N\')
{
v = \'-\' + v.Substring(1);
}
else
{
v = v.Substring(1);
}
}
if (fp.hasDecimal)
{
v = v.Substring(0, v.Length - 2) + \'.\' + v.Substring(v.Length - 2, 2);
}
field.SetValue(t, (decimal)decimal.Parse(v, CultureInfo.InvariantCulture));
}
else if (field.FieldType == typeof(DateTime))
{
DateTime dv;
if (v == "00000000")
{
dv = default(DateTime);
}
else
{
dv = DateTime.ParseExact(v, "yyyyMMdd", CultureInfo.InvariantCulture);
}
field.SetValue(t, dv);
}
else
{
throw new ApplicationException("unknown type");
}
}
return t;
}
public static void WriteFile(string filename, RegistroDeclarante declarante, List<RegistroDetalle> detalle)
{
declarante.NumeroTotalDeRegistrosDecl = detalle.Count;
declarante.SumaTotalValoracion1 = detalle.Sum(x => x.Valoracion1);
declarante.SumaTotalValoracion2 = detalle.Sum(x => x.Valoracion2);
using (StreamWriter file = new StreamWriter(filename, false, Encoding.GetEncoding(28591)))
{
char[] buffer = new char[500];
WriteBuffer<RegistroDeclarante>(declarante, buffer);
file.Write(buffer);
foreach (RegistroDetalle det in detalle)
{
WriteBuffer<RegistroDetalle>(det, buffer);
file.Write(buffer);
}
}
}
public static void ReadFile(string filename, out RegistroDeclarante declarante, out List<RegistroDetalle> detalle )
{
declarante = null;
detalle = new List<RegistroDetalle>();
using (StreamReader file = new StreamReader(filename, Encoding.GetEncoding(28591)))
{
char[] buffer = new char[500];
while (true)
{
int amountRead = file.ReadBlock(buffer, 0, 500);
if (amountRead == 0)
break;
if (amountRead != 500)
throw new ApplicationException("Corrupt file");
if (buffer[0] == \'1\')
{
declarante = ParseBuffer<RegistroDeclarante>(buffer);
}
else if (buffer[0] == \'2\')
{
detalle.Add(ParseBuffer<RegistroDetalle>(buffer));
}
else
{
throw new ApplicationException("corrupt file");
}
}
}
}
}
}